我昨晚发布了一个类似的问题(Rust lifetime error expected concrete lifetime but found bound lifetime),但现在仍然不知道如何将其应用于此情况。再次,下面是一个简化的示例:

struct Ref;

struct Container<'a> {
  r : &'a Ref
}

struct ContainerB<'a> {
  c : Container<'a>
}

trait ToC {
  fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> Self;
}

impl<'b> ToC for ContainerB<'b> {
  fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
    ContainerB{c:c}
  }
}

带有错误消息:
test.rs:16:3: 18:4 error: method `from_c` has an incompatible type for trait: expected concrete lifetime, but found bound lifetime parameter 'a
test.rs:16   fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
test.rs:17     ContainerB{c:c}
test.rs:18   }
test.rs:16:67: 18:4 note: expected concrete lifetime is the lifetime 'b as defined on the block at 16:66
test.rs:16   fn from_c<'a>(r : &'a Ref, c : Container<'a>) -> ContainerB<'a> {
test.rs:17     ContainerB{c:c}
test.rs:18   }
error: aborting due to previous error

我认为需要发生的是,我需要某种方式来等同/子化生命周期'a和生命周期'b。与前面的示例不同,没有&self可以使用。我想我可以通过向我的trait(trait ToC<'a> ...)添加一个生命周期类型参数来做到这一点,但是我不愿意这样做,因为它在我想将trait用作类型绑定(bind)的任何地方都添加了额外的<'a>

如果有人好奇(AKA可以忽略这一点),我可能会在库中使用它在rust和python类型之间进行转换。特征是here。一切正常,但是我试图围绕PyObject类型(例如numpy ndarray)实现一个包装器,并能够以此与PyObject进行相互转换。

再次感谢!

最佳答案

归结为与您上一个问题大致相同的问题。
Self指的是您要实现特征的类型。在这种情况下,它是ContainerB<'b>,因此关于它的不同之处的整体适用;这次,这一次也没有将'b'a bundle 在一起的任何方法;生存期是并且必须由编译器假定是可能不相交的。 (这与保证&'a ContainerB<'b>'b ≥ 'a不同)。

一旦使用了在方法上定义的生存期,就不可能将生存期与Self绑定(bind)在一起。最好的解决方案是将生命周期参数从方法转移到特征上:

trait ToC<'a> {
    fn from_c(r: &'a Ref, c: Container<'a>) -> Self;
}

impl<'a> ToC<'a> for ContainerB<'a> {
    fn from_c(r: &'a Ref, c: Container<'a>) -> ContainerB<'a> {
        ContainerB { c: c }
    }
}

关于rust - 在Self上分类不同的生存期和方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24853111/

10-12 23:05