簡體   English   中英

如何在Rust中提供通用結構的實現?

[英]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>的快捷方式。


備注

  1. 本答案解釋了impl<T>的原因。 從本質上講,它歸結為impl<T> MyStruct<T>impl MyStruct<T>都有效,但意味着不同的事實。

  2. 當您將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM