如何为泛型 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 = i32
为 i32
实现 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);
}
这种行为可能会通过更智能的特征求解器得到改善,因为在您的特定情况下,唯一适用的实现是 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);
}
要了解有关特征和完全限定语法的更多信息,请查看 The Book's chapter on advanced traits.
我正在尝试建立我对 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 = i32
为 i32
实现 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);
}
这种行为可能会通过更智能的特征求解器得到改善,因为在您的特定情况下,唯一适用的实现是 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);
}
要了解有关特征和完全限定语法的更多信息,请查看 The Book's chapter on advanced traits.