我是 Rust 新手,我正在尝试找出在 Rust 中执行以下操作的最佳方法是什么:
struct ThingIterator {
current: String,
stop: String,
}
impl Iterator for ThingIterator {
type Item = &str;
fn next(&mut self) -> Option<&str> {
if self.current == self.stop {
return None;
}
// For testing
self.current = self.stop;
Some(&self.current)
}
}
fn main() {
let pi = ThingIterator {
current: String::from("Ask"),
stop: String::from("Zoo"),
};
println!("Number of things={}", pi.count());
}
Run Code Online (Sandbox Code Playgroud)
我的错误是:
error[E0106]: missing lifetime specifier
--> src/main.rs:7:17
|
7 | type Item = &str;
| ^ expected lifetime parameter
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)
这是有道理的,我需要指定从 next() 返回的引用的有效时间。我猜测对于函数本身来说它很好,因为生命周期被省略了(不确定省略的共轭) - 但我以某种方式需要定义“type Item = &str”行的生命周期。
就我而言,只要“当前”有效,即与“自我”具有相同的生命周期,它就有效。
我没有在 Rust 书籍或其他文档中看到任何可以帮助我解决这个问题的内容。
PS 抱歉,如果我破坏了术语,我对 Rust 非常陌生。谢谢
&mut self定义 type 时, in的生命周期next不在范围内Item,因此Item不能依赖于该生命周期。相反,通常使用ThingIterator保留引用而不是拥有的数据。如果仍然存在拥有数据的结构,您可能会实现IntoIteratorfor&OwnsData来转换为使用引用的类型。
// ThingIterator is now generic in the lifetime 'a
// and it holds references rather than owned Strings.
struct ThingIterator<'a> {
current: &'a str,
stop: &'a str,
}
impl<'a> Iterator for ThingIterator<'a> {
// Now we can use the lifetime from ThingIterator here.
type Item = &'a str;
fn next(&mut self) -> Option<&'a str> {
if self.current == self.stop {
return None;
}
// For testing
self.current = self.stop;
Some(self.current)
}
}
// Typically, you'll have a type that owns its data
// Like Vec<T>, HashSet<T>, etc.
struct OwnsData {
current: String,
stop: String,
}
impl OwnsData {
// We'll have the traditional method that takes a reference
// to self and returns an iterator over references into self.
// Explicit lifetimes aren't needed, but it might help with understanding.
// fn iter<'a>(&'a self) -> ThingIterator<'a> {
fn iter(&self) -> ThingIterator {
ThingIterator {
current: &self.current,
stop: &self.stop,
}
}
}
// Then, we'll implement IntoIterator for references to OwnsData
// using the OwnsData::iter method defined above.
// This is helpful because for loops and many iterator methods
// use IntoIterator to work.
impl<'a> IntoIterator for &'a OwnsData {
// We'll be converting into ThingIterator
type IntoIter = ThingIterator<'a>;
type Item = &'a str;
fn into_iter(self) -> ThingIterator<'a> {
self.iter()
}
}
fn main() {
let pi = ThingIterator {
current: "Ask",
stop: "Zoo",
};
println!("Number of things={}", pi.count());
// Alternatively, we could start with Strings
// and use OwnsData
let tau = OwnsData {
current: "Ask".to_string(),
stop: "Zoo".to_string(),
};
println!("Number of things={}", tau.iter().count());
}
Run Code Online (Sandbox Code Playgroud)
也可以看看
PS你要找的词是“elided”。