我来自C++社区,切换到Rust...并玩Rust泛型,有人能解释为什么我在这个虚拟示例中得到这个错误吗?
struct FF<T1, T2>(T1, T2);
trait FFt<T1, T2> {
type t1 = T1;
type t2 = T2;
fn call<t1, t2>(&self, t_1: Self::t1, t_2: Self::t2);
};
impl<T1, T2> FFt<T1, T2> for FF<T1, T1> {
fn call<T1, T2>(&self, t_1: Self::t1, t_2: Self::t2) {
t_1.a = 1;
t_2.b = 1;
}
}
struct AA {
a: i32,
b: i32,
}
let fff: FF<AA, AA> = FF(AA { a: 0, b: 0 }, AA { a: 0, b: 0 });
fff.call(AA { a: 0, b: 0 }, AA { a: 0, b: 0 }); // <----- ERROR LINE !!!
错误:
error[E0609]: no field `a` on type `T1`
--> p2p/./src/lib.rs:172:17
|
170 | impl<T1,T2> FFt<T1,T2> for FF<T1,T1> {
| -- type parameter 'T1' declared here
171 | fn call<T1,T2>(&self,t_1 : Self::t1,t_2 : Self::t2) {
172 | t_1.a = 1;
| ^
error[E0609]: no field `b` on type `T2`
--> p2p/./src/lib.rs:173:17
|
170 | impl<T1,T2> FFt<T1,T2> for FF<T1,T1> {
| -- type parameter 'T2' declared here
...
173 | t_2.b = 1;
| ^
1条答案
按热度按时间fumotvh31#
你可能想读一读生 rust 的书,因为你有一个不太好的开始。
有人能解释一下为什么我在这个虚拟的例子中得到这个错误吗?
因为C泛型和Rust泛型的工作原理完全不同。
C模板将被类型替换,然后检查,所以只要你传递一个适合正在使用的类型,它就可以工作。
Rust泛型是基于 constraints 的,它们的类型检查独立于示例化,并且只在约束允许的情况下工作。约束是通过 traits 指定的。我听说C++ Concepts 工作类似,尽管我没有这方面的经验。
在这里,泛型类型是无约束的,所以就编译器而言,它们是 * 不可能 * 的,编译器几乎只会假设它们是
Sized
。还
这没有多大意义,泛型类型参数的意义在于 caller 决定它是什么,关联类型的意义在于 implementor 决定它是什么(但每个实现只能有一个)。
然后呢
这意味着
call
有两个泛型参数t1
和t2
(不正确的命名约定),它们也是无约束的,并且完全独立于T1
/T2
和FFt::t1
/FFt::t2
。