如何为泛型 impl 的使用提供合适的类型?

How to provide a proper type for use of generic impl?

我正在尝试建立我对 Rust 中关联类型的直觉。在我的实验中,我构建了泛型和 impl 的这种(无意义的)组合。

struct MyStruct<T>{
    t:T
}

trait MyTrait {
    type T1;
    fn tt(x:Self::T1) -> MyStruct<Self::T1>;
}

impl<T> MyTrait for MyStruct<T> {
    type T1=T;
    fn tt(a:Self::T1) -> MyStruct<Self::T1> {
        MyStruct{t:a}
    }

}

可以编译,但问题是我不能使用'tt'函数。


fn main() {
    let x = MyTrait::tt(1);
}

导致错误:cannot infer type

我已经尝试过我的选项来为 Rust 提供类型提示,但我尝试的次数越多,(对我而言)错误消息就越难听到。

谁能给我提供上面的 MyTrait::tt 函数的使用示例,或者这是死胡同?如果是,为什么?

使用类似 MyTrait::tt(1) 的问题是无法从参数 1 中推断出实现 MyTrait 的实际类型。例如,您可以为 String 实现 MyTrait,但使 T1 成为 i32。通过该设置,MyTrait::tt(1) 可以引用 <String as MyTrait>::tt(使用完全限定的方法调用语法)。另一方面,您也可以使用 T1 = i32i32 实现 MyTrait。那么 MyTrait::tt(1) 也可以引用 <i32 as MyTrait>::tt.

impl MyTrait for String {
    type T1 = i32;
    fn tt(x: i32) -> MyStruct<i32> {
        MyStruct { t: x }
    }
}

impl MyTrait for i32 {
    type T1 = i32;
    fn tt(x: i32) -> MyStruct<i32> {
        MyStruct { t: x }
    }
}

fn main() {
    let x = 47_i32;

    // let y = MyTrait::tt(x);
    // That could refer to either of the following
    let y = <String as MyTrait>::tt(x);
    let z = <i32 as MyTrait>::tt(x);

    // Of course, you don't need the fully qualified syntax
    // all the time.
    let y2 = String::tt(x);
    let z2 = i32::tt(x);
}

(playground)

这种行为可能会通过更智能的特征求解器得到改善,因为在您的特定情况下,唯一适用的实现是 MyStruct<i32> 上的实现。但现在,我只使用 <MyStruct<i32> as MyTrait>::tt(1) 或简单地使用 MyStruct::tt(1).

fn main() {
    let x = <MyStruct<i32> as MyTrait>::tt(1);
    let x = MyStruct::tt(1);
}

(playground)

要了解有关特征和完全限定语法的更多信息,请查看 The Book's chapter on advanced traits.