【问题标题】:Switching from struct with lifetime to trait从具有生命周期的结构切换到特征
【发布时间】:2015-08-01 06:18:05
【问题描述】:

我正在尝试创建一个 trait 来将某些东西作为 &Strings 的迭代器呈现。如果我在 get_iterator 中使用 struct std::slice::Iter 结果一切正常。

pub trait Value {
    fn get_iterator(&self) -> Box<std::slice::Iter<String>>;
}

struct StringList {
    strings: Vec<String>
}

impl Value for StringList {
    fn get_iterator(&self) -> Box<std::slice::Iter<String>> {
        Box::new(self.strings.iter())
    }
}

fn main() {
}

但是当我切换到 trait Iterator

pub trait Value {
    fn get_iterator(&self) -> Box<Iterator<Item=&String>>;
}

struct StringList {
    strings: Vec<String>
}

impl Value for StringList {
    fn get_iterator(&self) -> Box<Iterator<Item=&String>> {
        Box::new(self.strings.iter())
    }
}

fn main() {
}

rust 抱怨生命周期:

<anon>:11:31: 11:37 error: cannot infer an appropriate lifetime for lifetime parameter 'a in function call due to conflicting requirements
<anon>:11         Box::new(self.strings.iter())

我应该如何定义 trait 并进行实现以使其发挥作用?

顺便说一句,为什么编译器将这个生命周期称为“a”?它没有在任何地方命名,并且通常 rust 符合“匿名生命周期”。这是一个应该报告的错误吗?

【问题讨论】:

  • 我不认为你可以装箱任何具有非静态生命周期的东西。此外,在引用时不应使用 '&String' 而应使用 '&str'。我也看不出你在标题中提到的特质在哪里。
  • 我说的是get_iterator方法的结果。在第一种情况下,它是 struct (std::slice::Iter),在第二种情况下,它是 trait (Iterator)。 &String 这里只是一个例子,在项目中我想使用更复杂的东西。如果我在这里使用 &str,我将不得不为 Iterator 创建另一个结构,因为 std::slice::Iter 不能自动转换为 std::slice::Iter。
  • 实际上我可以将具有非静态生命周期的东西装箱:fn get_first_item(x: &amp;Vec&lt;String&gt;) -&gt; Box&lt;&amp;str&gt; { Box::new(&amp;x[0]) } 工作得很好。

标签: struct rust traits lifetime


【解决方案1】:

我们希望在我们的 StringList 引用上声明一个新的生命周期,并确保我们返回的、装箱的 Iterator 特征受该生命周期的约束。

pub trait Value {
    fn get_iterator<'a>(&'a self) -> Box<Iterator<Item=&String> + 'a>;
}

struct StringList {
    strings: Vec<String>
}

impl Value for StringList {
    fn get_iterator<'a>(&'a self) -> Box<Iterator<Item=&String> + 'a> {
        Box::new(self.strings.iter())
    }
}

fn main() {
}

编辑: 要回答你关于生命周期'a 的问题,它实际上是定义的,但文档没有显示它。单击 Vec 文档中的 Iter 返回对象,您将看到在该对象上声明了 'a。 Vec 的实现必须在调用 iter() 时将生命周期 'a 引入到 Vec 引用中。

【讨论】:

猜你喜欢
  • 2019-08-05
  • 1970-01-01
  • 2015-04-22
  • 1970-01-01
  • 2019-02-24
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多