gpt4 book ai didi

generics - 如何在 Rust 中提供通用结构的实现?

转载 作者:行者123 更新时间:2023-11-29 07:54:09 25 4
gpt4 key购买 nike

我有一个结构MyStruct,它接受一个通用参数T: SomeTrait,我想为实现一个方法我的结构。这有效:

/// 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 block 中,如下所示:

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<...>变得太长,您可以使用 where -语法并分别列出约束:

impl<T> MyStruct<T>
where
T: SomeTrait,
{
fn new(t: T) -> Self {
MyStruct { value: t }
}
}

注意 Self 的用法, 这是 MyStruct<T> 的快捷方式在 impl 内可用 block 。


备注

  1. 原因impl<T>需要在 this answer 中解释.从本质上讲,它归结为一个事实 impl<T> MyStruct<T>impl MyStruct<T>有效,但含义不同。

  2. 当你移动时new进入impl block ,你应该删除多余的类型参数,否则你的结构的接口(interface)将变得不可用,如下例所示:

    // 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.
    }

关于generics - 如何在 Rust 中提供通用结构的实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54504026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com