如何在 trait impls 中使用外部类型作为泛型类型参数
How to use the outer type for a generic type parameter in trait impls
我有一个最小的例子如下。
有两个特征,TraitA
和 TraitB
。 TraitB
有一个使用 TraitA
作为类型参数的通用函数。 TraitB
必须是对象安全的,所以我用 where Self: Sized
标记函数。目前为止一切正常。
如果我有一个结构MyStruct<A: TraitA>
,我想为它实现TraitB
。 impl
块将有 impl<A: TraitA> TraitB for MyStruct<A>
。但对于 generic_func
,编译器会抱怨 A 已被使用。我无法编译代码,因为我不知道用什么来代替“???”在示例中。
use std::marker::PhantomData;
// One trait
trait TraitA {}
// The other trait that has one generic function that uses TraitA
trait TraitB {
fn generic_func<A: TraitA>(self) where Self: Sized;
}
// TraitB needs to be object safe
fn foo(a: &dyn TraitB) {
}
// The generic struct that uses TraitA, but needs to implement TraitB as well.
struct MyStruct<A: TraitA>(PhantomData<A>);
impl<A: TraitA> TraitB for MyStruct<A> {
// What should I put as ???. It should refer to A.
fn generic_func<???>(self) where Self: Sized {
}
}
Rust 游乐场link:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4eff9e5a6fded93e03a090890f84e983
任何字母都可以。 C
、D
、Potato
等,Rust 不关心泛型变量是否具有相同的 name,只是它们是以相同的方式使用(即无论你命名它需要什么 : TraitA
)
impl<A: TraitA> TraitB for MyStruct<A> {
fn generic_func<Potato: TraitA>(self) where Self: Sized {
}
}
如您所写,TraitB
需要 generic_func
适用于 每个 实现 TraitA
的类型。如果你想让它为特定的工作,你需要以不同的方式写你的特质。
trait TraitB {
type MyA: TraitA;
fn generic_func(self);
}
impl<A: Trait> TraitB for MyStruct<A> {
type MyA = A;
fn generic_func(self) { ... }
}
现在,在 trait 内部,Self::MyA
指的是 特定类型,您正在实现此 trait 以使用它。
我有一个最小的例子如下。
有两个特征,TraitA
和 TraitB
。 TraitB
有一个使用 TraitA
作为类型参数的通用函数。 TraitB
必须是对象安全的,所以我用 where Self: Sized
标记函数。目前为止一切正常。
如果我有一个结构MyStruct<A: TraitA>
,我想为它实现TraitB
。 impl
块将有 impl<A: TraitA> TraitB for MyStruct<A>
。但对于 generic_func
,编译器会抱怨 A 已被使用。我无法编译代码,因为我不知道用什么来代替“???”在示例中。
use std::marker::PhantomData;
// One trait
trait TraitA {}
// The other trait that has one generic function that uses TraitA
trait TraitB {
fn generic_func<A: TraitA>(self) where Self: Sized;
}
// TraitB needs to be object safe
fn foo(a: &dyn TraitB) {
}
// The generic struct that uses TraitA, but needs to implement TraitB as well.
struct MyStruct<A: TraitA>(PhantomData<A>);
impl<A: TraitA> TraitB for MyStruct<A> {
// What should I put as ???. It should refer to A.
fn generic_func<???>(self) where Self: Sized {
}
}
Rust 游乐场link:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4eff9e5a6fded93e03a090890f84e983
任何字母都可以。 C
、D
、Potato
等,Rust 不关心泛型变量是否具有相同的 name,只是它们是以相同的方式使用(即无论你命名它需要什么 : TraitA
)
impl<A: TraitA> TraitB for MyStruct<A> {
fn generic_func<Potato: TraitA>(self) where Self: Sized {
}
}
如您所写,TraitB
需要 generic_func
适用于 每个 实现 TraitA
的类型。如果你想让它为特定的工作,你需要以不同的方式写你的特质。
trait TraitB {
type MyA: TraitA;
fn generic_func(self);
}
impl<A: Trait> TraitB for MyStruct<A> {
type MyA = A;
fn generic_func(self) { ... }
}
现在,在 trait 内部,Self::MyA
指的是 特定类型,您正在实现此 trait 以使用它。