![](/img/trans.png)
[英]How do I implement this API? It's a Builder pattern that takes generic (or trait) params
[英]How do I implement a trait with a generic method?
我正在尝试实现一个包含通用方法的特征。
trait Trait {
fn method<T>(&self) -> T;
}
struct Struct;
impl Trait for Struct {
fn method(&self) -> u8 {
return 16u8;
}
}
我得到:
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
我应该如何正确编写impl
块?
函数和方法中的类型参数是通用的。 这意味着对于所有 trait 实现者, Trait::method<T>
必须为任何T
实现,其约束与 trait 指示的约束完全相同(在这种情况下, T
上的约束只是隐式的Sized
)。
您指出的编译器错误消息表明它仍然需要参数类型T
。 相反,您的Struct
实现假设T = u8
,这是不正确的。 类型参数由方法的调用者而不是实现者决定,因此T
可能并不总是u8
。
如果您希望让实现者选择特定类型,则必须改为在关联类型中具体化。
trait Trait {
type Output;
fn method(&self) -> Self::Output;
}
struct Struct;
impl Trait for Struct {
type Output = u8;
fn method(&self) -> u8 {
16
}
}
另请阅读The Rust 编程语言: 在具有关联类型的 trait 定义中指定占位符类型的这一部分。
也可以看看:
除了使用关联类型的方法之外,从这个答案中,您还可以将泛型添加到特征中。
trait Trait<T> {
fn method(&self) -> T;
}
impl Trait<u8> for Struct {
fn method(&self) -> u8 {
16
}
}
当只有一种特征的逻辑形式可供使用时,您可以使用“关联类型”方式。 当存在多个有意义的输出类型时,您可以使用通用特征,例如这是合法的:
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);
}
据我所知,你不能用基于关联类型的特征来做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.