Rust 我能强迫一个特征是协变的吗?
多亏了@francis gagné的另一个问题,我对方差的工作原理有了更清晰的认识。例如,包含引用的类型在其生存期参数中是协变的,如下所示Rust 我能强迫一个特征是协变的吗?,rust,traits,covariance,Rust,Traits,Covariance,多亏了@francis gagné的另一个问题,我对方差的工作原理有了更清晰的认识。例如,包含引用的类型在其生存期参数中是协变的,如下所示 struct Foo<'a> (PhantomData<&'a str>); /// Foo is covariant over its lifetime parameter pub fn test_foo<'a:'b, 'b:'c, 'c>() { let fa: Foo<'a> = Foo
struct Foo<'a> (PhantomData<&'a str>);
/// Foo is covariant over its lifetime parameter
pub fn test_foo<'a:'b, 'b:'c, 'c>() {
let fa: Foo<'a> = Foo(PhantomData);
let fb: Foo<'b> = Foo(PhantomData);
let fc: Foo<'c> = Foo(PhantomData);
let v: Vec<Foo<'b>> = vec![fa, fb]; // fc is not accepted
}
impl<'a> Baz<'a> for Foo<'a> {}
impl<'a> Baz<'a> for Bar<'a> {}
structfoo);
///Foo在其生命周期参数上是协变的
pub fn test_foo=foo(幻影数据);
设fb:Foo=Foo(PhantomData);
设v:Vec(PhantomData(){
设ba:Bar=Bar(幻影数据);
让bc:Bar>=vec![bb,bc];//不接受ba
}
最后,具有寿命参数的特征在其寿命参数上是不变的
struct Bar<'a> (PhantomData<fn(&'a str)>);
/// Bar is contravariant over its lifetime parameter
pub fn test_bar<'a:'b, 'b:'c, 'c>() {
let ba: Bar<'a> = Bar(PhantomData);
let bb: Bar<'b> = Bar(PhantomData);
let bc: Bar<'c> = Bar(PhantomData);
let v: Vec<Bar<'b>> = vec![bb, bc]; // ba is not accepted
}
pub trait Baz<'a> {}
impl<'a> Baz<'a> for () {}
/// Baz is invariant over its lifetime parameter
pub fn test_baz<'a:'b, 'b:'c, 'c>() {
let za: Box<dyn Baz<'a>> = Box::new(());
let zb: Box<dyn Baz<'b>> = Box::new(());
let zc: Box<dyn Baz<'c>> = Box::new(());
let v: Vec<Box<dyn Baz<'b>>> = vec![zb]; // za and zx are not accepted
}
pub trait Baz Baz(){
让za:Box>=Box::new(());
设zc:Box>>=vec![zb];//不接受za和zx
}
这是有意义的,因为该特征可以通过协变和逆变类型实现,如下所示
struct Foo<'a> (PhantomData<&'a str>);
/// Foo is covariant over its lifetime parameter
pub fn test_foo<'a:'b, 'b:'c, 'c>() {
let fa: Foo<'a> = Foo(PhantomData);
let fb: Foo<'b> = Foo(PhantomData);
let fc: Foo<'c> = Foo(PhantomData);
let v: Vec<Foo<'b>> = vec![fa, fb]; // fc is not accepted
}
impl<'a> Baz<'a> for Foo<'a> {}
impl<'a> Baz<'a> for Bar<'a> {}
impl for Foo Baz{}
我的问题是:我能强迫一个特征在其生命周期参数中是协变的吗?我期望一个标记特征,例如:
trait Baz<'a>: Covariant<'a> {}
trait Baz{}
这将使使用逆变类型实现该特征是非法的,并允许za
成为上述test_baz
函数中向量v
的成员
当然,能够做相反的事情(强迫一个特征是反变的)也很有用
没有
您可以表示“一个实现
Baz的值。我找到了一个解决方法。我没有将特征标记为协变(正如@trentcl所指出的,在Rust 1.31中不可能),而是让该类型在小于自身生命周期的所有生命周期内实现特征:
impl<'a:'b, 'b> Baz<'b> for Foo<'a> {}
impl for Foo
和Foo
是必需的:
pub fn test_baz<'a:'b, 'b:'c, 'c>() {
let fa: Foo<'a> = Foo(PhantomData);
let fb: Foo<'b> = Foo(PhantomData);
let fc: Foo<'c> = Foo(PhantomData);
let v: Vec<&dyn Baz<'b>> = vec![&fa, &fb]; // &fc is not accepted
}
pub fn test_baz=Foo(幻影数据);
设fb:Foo=Foo(PhantomData);
let v:VecI想添加更多的细节,或者提出一个有用的建议,但是很难说这个问题到底是为了什么,所以这是一个简单的答案。如果你有具体的代码需要这样的特性,我很想看一个示例,也许然后我可以提一个建议。我的问题很复杂,很难总结我甚至不确定协变特征是否是我所需要的解决方案……我主要是想更好地理解整体情况。这里是一个例子。有人可能会发现它很有用。