简体   繁体   English

Traits,通过返回 `Self::Item` 的 trait 方法返回对拥有字段的引用

[英]Traits, returning a reference to an owned field via a trait method that returns `Self::Item`

Returning a reference to an owned field is allowed in other scenarios.在其他情况下允许返回对拥有字段的引用。 For instance, the code below compiles fine.例如,下面的代码编译得很好。

struct Charlie<T> {
    delta: T,
}

impl<T> Charlie<T> {
    fn delta(&self) -> &T
    {
        &self.delta
    }
}

I'd like to return a reference to an owned field from a trait method in similar fashion.我想以类似的方式从 trait 方法返回对拥有字段的引用。 Assume that Alpha is a trait in the standard library, so I can't modify it.假设Alpha是标准库中的一个特征,所以我不能修改它。

Is there a way to implement this?有没有办法实现这个?

trait Alpha {
    type Item;
    fn bravo(&mut self) -> Self::Item;
}

impl<T> Alpha for Charlie<T> {
    type Item = &T;
    
    fn bravo(&mut self) -> Self::Item
    {
        &self.delta
    }
}

The above doesn't compile and the error messages don't seem to apply.以上内容无法编译,并且错误消息似乎不适用。 If I try following the error message suggestions, things just get complicated and I run into a series of errors with suggestions that also don't pan out.如果我尝试遵循错误消息建议,事情就会变得复杂,并且我会遇到一系列错误,并且建议也不会成功。

   Compiling playground v0.0.1 (/playground)
error[E0106]: missing lifetime specifier
  --> src/main.rs:22:17
   |
22 |     type Item = &T;
   |                 ^ expected named lifetime parameter
   |
help: consider introducing a named lifetime parameter
   |
22 |     type Item<'a> = &'a T;
   |              ^^^^   ^^^

I've tried the above suggestion and went so far as to declare 'a on Charlie 's struct and add a PhantomData field, and thoroughly peppered the rest of my sources with 'a s.我已经尝试了上述建议,甚至在Charlie的结构上声明'a并添加一个PhantomData字段,并用'a s. And the compiler continues whining and complaining and nagging throughout the whole process.编译器在整个过程中不断地抱怨、抱怨和唠叨。

I managed to find this post on StackOverflow , but the solutions there seem to all require modifying the trait.我设法在 StackOverflow 上找到了这篇文章,但那里的解决方案似乎都需要修改特征。

I'm thinking what I'm trying to do may not be possible.我在想我想做的事情可能是不可能的。 But I don't really understand why not.但我真的不明白为什么不。

The Alpha trait method that I was struggling with is actually我一直在努力的Alpha trait 方法实际上是

    type Item = Take<&I>;
    fn next(&mut self) -> Option<Self::Item> { ... }

I was trying to return another wrapped iterator type, where I is the wrapped iterator.我试图返回另一个包装的迭代器类型, I是包装的迭代器。 The Iterator trait itself doesn't define any lifetimes I can leverage. Iterator trait 本身并没有定义我可以利用的任何生命周期。

I do know a way to implement around this limitation using the smart pointer classes to encapsulate the field I want to share in Charlie .我确实知道一种解决此限制的方法,使用智能指针类来封装我想在Charlie中共享的字段。 Then make that my Item type.然后将其设为我的Item类型。 I was just hoping for something with less overhead.我只是希望开销更少的东西。

The contract for that trait unfortunately doesn't allow it.不幸的是,该特征的合同不允许这样做。

trait Alpha {
  type Item;
  fn bravo(&mut self) -> Self::Item;
}

This says that, if Self is an Alpha , then "there exists some single Self::Item which I can get from any &mut self with any lifetime".这就是说,如果SelfAlpha ,那么“存在一些单一的Self::Item ,我可以在任何生命周期内从任何&mut self获得”。 You want "there exists a class of Self::Item whose lifetimes relate to &mut self in a nontrivial way".您想要“存在一个Self::Item的 class ,其生命周期与&mut self以一种重要的方式相关”。

The easiest way to get around this is to make bravo take self by value.解决这个问题的最简单方法是让bravo重视self

trait Alpha {
  type Item;
  fn bravo(self) -> Self::Item;
}

Now, the contract says "there's some way to get a Self::Item from a self ", which is much simpler.现在,合同说“有一些方法可以从一个self中获取一个Self::Item ”,这要简单得多。 We can implement it as我们可以将其实现为

impl<'a, T> Alpha for Charlie<&'a mut T> {
  type Item = &'a T;
    
  fn bravo(self) -> Self::Item {
    &self.delta
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实现一个特征方法,返回一个拥有类型的有界生命周期引用 - Implementing a trait method returning a bounded lifetime reference for owned type 如何使用包含返回对 Self 的引用的方法的 trait 对象? - How to use a trait object that contains a method that returns a reference to Self? 将可变的自引用传递给拥有对象的方法 - Passing mutable self reference to method of owned object Trait方法,可以实现返回引用或拥有值 - Trait method that can be implemented to either return a reference or an owned value 如何将可变自引用传递给特征方法? - How to pass a mutable self reference on to a trait method? 在 trait 中定义一个方法,返回 Self 的默认实现 - Define a method in trait returning a default implementation of Self 从 trait 方法返回对结构字段的可变引用时,如何修复生命周期不匹配? - How do I fix the lifetime mismatch when returning a mutable reference to the struct's field from a trait method? 如何编写一种将“ self”作为可变特征引用添加到集合的方法? - How to write a method that adds `self` as a mutable trait reference to a collection? 如何编写具有返回引用的方法并正确实现它的特征? - How to write a trait that has a method returning a reference and implement it correctly? 返回对 Box 的引用<dyn trait></dyn> - Returning a reference to a Box<dyn Trait>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM