【发布时间】:2022-11-23 20:18:30
【问题描述】:
我来自 C++ 社区,切换到 Rust...,并使用 rust-generics,任何人都可以解释为什么我在这个虚拟示例中收到此错误吗?谢谢你。
struct FF<T1,T2>(T1,T2);
trait FFt<T1,T2>{
type t1 = T1;
type t2 = T2;
fn call<t1,t2>(&self, Self::t1, 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;
| ^
【问题讨论】:
-
因为
FFt类型中的T1、T2类型是任何类型的占位符。不知道a或b字段是否真的存在于具体类型中。例如,如果我输入FF<u32, u32>会怎样? -
假设你做了
let fff: FF<i32, i32> = FF(1, 2); fff.call(3, 4);没有4.b的1.a可以访问。如果您需要访问结构的特定字段,则需要通过通过方法公开该字段的特征来绑定泛型类型,或者不使用泛型,而是使用要使用的特定类型。 -
在这方面,Rust 与 C++ 的行为不同:C++ 允许你“去看看你能走多远”,基本上是鸭式输入,看看模板参数是否有成员
a。另一方面,Rust 要求您指定要对泛型类型执行的操作。 AFAIK 无法指定类型将具有成员a- 相反,您可能希望具有可能具有fn a() -> i32的特征,然后调用a(),您在 C++ 中只需访问成员 @987654334 @.