[英]How do I provide an implementation of a generic struct in Rust?
我有一个结构MyStruct
,它采用通用参数T: SomeTrait
,我想为MyStruct
实现一个new
方法。 这有效:
/// Constraint for the type parameter `T` in MyStruct
pub trait SomeTrait: Clone {}
/// The struct that I want to construct with `new`
pub struct MyStruct<T: SomeTrait> {
value: T,
}
fn new<T: SomeTrait>(t: T) -> MyStruct<T> {
MyStruct { value: t }
}
fn main() {}
我想把new
函数放在这样的impl
块中:
impl MyStruct {
fn new<T: SomeTrait>(t: T) -> MyStruct<T> {
MyStruct { value: t }
}
}
但是无法编译:
error[E0107]: wrong number of type arguments: expected 1, found 0
--> src/main.rs:9:6
|
9 | impl MyStruct {
| ^^^^^^^^ expected 1 type argument
如果我试着这样说:
impl MyStruct<T> {
fn new(t: T) -> MyStruct<T> {
MyStruct { value: t }
}
}
错误更改为:
error[E0412]: cannot find type `T` in this scope
--> src/main.rs:9:15
|
9 | impl MyStruct<T> {
| ^ not found in this scope
如何提供通用结构的实现? 我在哪里放置通用参数及其约束?
类型参数<T: SomeTrait>
应该在impl
关键字后面:
impl<T: SomeTrait> MyStruct<T> {
fn new(t: T) -> Self {
MyStruct { value: t }
}
}
如果impl<...>
中的类型和约束impl<...>
变得太长,您可以使用where
-syntax并分别列出约束:
impl<T> MyStruct<T>
where
T: SomeTrait,
{
fn new(t: T) -> Self {
MyStruct { value: t }
}
}
请注意Self
的用法,它是impl
块内部可用的MyStruct<T>
的快捷方式。
备注
本答案解释了impl<T>
的原因。 从本质上讲,它归结为impl<T> MyStruct<T>
和impl MyStruct<T>
都有效,但意味着不同的事实。
当您将new
移动到impl
块时,应该删除多余的类型参数,否则结构的接口将变得不可用,如以下示例所示:
// trait SomeTrait and struct MyStruct as above // [...] impl<T> MyStruct<T> where T: SomeTrait, { fn new<S: SomeTrait>(t: S) -> MyStruct<S> { MyStruct { value: t } } } impl SomeTrait for u64 {} impl SomeTrait for u128 {} fn main() { // just a demo of problematic code, don't do this! let a: MyStruct<u128> = MyStruct::<u64>::new::<u128>(1234); // ^ // | // This is an irrelevant type // that cannot be inferred. Not only will the compiler // force you to provide an irrelevant type, it will also // not prevent you from passing incoherent junk as type // argument, as this example demonstrates. This happens // because `S` and `T` are completely unrelated. }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.