Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 我能强迫一个特征是协变的吗?_Rust_Traits_Covariance - Fatal编程技术网

Rust 我能强迫一个特征是协变的吗?

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

多亏了@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(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想添加更多的细节,或者提出一个有用的建议,但是很难说这个问题到底是为了什么,所以这是一个简单的答案。如果你有具体的代码需要这样的特性,我很想看一个示例,也许然后我可以提一个建议。我的问题很复杂,很难总结我甚至不确定协变特征是否是我所需要的解决方案……我主要是想更好地理解整体情况。这里是一个例子。有人可能会发现它很有用。