简体   繁体   English

如何使用泛型方法实现特征?

[英]How do I implement a trait with a generic method?

I'm trying to implement a trait which contains a generic method.我正在尝试实现一个包含通用方法的特征。

trait Trait {
    fn method<T>(&self) -> T;
}

struct Struct;

impl Trait for Struct {
    fn method(&self) -> u8 {
        return 16u8;
    }
}

I get:我得到:

error[E0049]: method `method` has 0 type parameters but its trait declaration has 1 type parameter
 --> src/lib.rs:8:5
  |
2 |     fn method<T>(&self) -> T;
  |     ------------------------- expected 1 type parameter
...
8 |     fn method(&self) -> u8 {
  |     ^^^^^^^^^^^^^^^^^^^^^^ found 0 type parameters

How should I write the impl block correctly?我应该如何正确编写impl块?

Type parameters in functions and methods are universal .函数和方法中的类型参数是通用的 This means that for all trait implementers, Trait::method<T> must be implemented for any T with the exact same constraints as those indicated by the trait (in this case, the constraint on T is only the implicit Sized ).这意味着对于所有 trait 实现者, Trait::method<T>必须为任何T实现,其约束与 trait 指示的约束完全相同(在这种情况下, T上的约束只是隐式的Sized )。

The compiler's error message that you indicated suggests that it was still expecting the parameter type T .您指出的编译器错误消息表明它仍然需要参数类型T Instead, your Struct implementation is assuming that T = u8 , which is incorrect.相反,您的Struct实现假设T = u8 ,这是不正确的。 The type parameter is decided by the caller of the method rather than the implementer, so T might not always be u8 .类型参数由方法的调用者而不是实现者决定,因此T可能并不总是u8

If you wish to let the implementer choose a specific type, that has to be materialized in an associated type instead.如果您希望让实现者选择特定类型,则必须改为在关联类型中具体化。

trait Trait {
    type Output;

    fn method(&self) -> Self::Output;
}

struct Struct;

impl Trait for Struct {
    type Output = u8;

    fn method(&self) -> u8 {
        16
    }
}

Read also this section of The Rust Programming Language : Specifying placeholder types in trait definitions with associated types .另请阅读The Rust 编程语言在具有关联类型的 trait 定义中指定占位符类型的这一部分。

See also:也可以看看:

In addition to the method using an associated type, from this answer , you can also add the generic to the trait.除了使用关联类型的方法之外,从这个答案中,您还可以将泛型添加到特征中。

trait Trait<T> {
    fn method(&self) -> T;
}

impl Trait<u8> for Struct {
    fn method(&self) -> u8 {
        16
    }
}

You use the "associated type" way when there is only one logical form of the trait to use.当只有一种特征的逻辑形式可供使用时,您可以使用“关联类型”方式。 You can use the generic trait when there is more than one output type that makes sense, for example this is legal:当存在多个有意义的输出类型时,您可以使用通用特征,例如这是合法的:

struct Struct;

trait Trait<T> {
    fn method(&self) -> T;
}

impl Trait<u8> for Struct {
    fn method(&self) -> u8 {
        16
    }
}

impl Trait<String> for Struct {
    fn method(&self) -> String {
        "hello".to_string()
    }
}

fn main() {
    let s = Struct;
    let a: u8 = s.method();
    let b: String = s.method();
    println!("a={}, b={}", a, b);
}

As far as I know, you can not do this with a trait based on associated types.据我所知,你不能用基于关联类型的特征来做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM