我是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());
}
我的错误是:
error[E0106]: missing lifetime specifier
--> src/main.rs:7:17
|
7 | type Item = &str;
| ^ expected lifetime parameter
error: aborting due to previous error
这很有意义,我需要指定next()返回的引用有效的时间。我猜测该函数本身很好,因为可以延长生命周期(不确定消除的共轭)-但我需要某种方式定义“类型Item =&str”行的生命周期。
在我的情况下,只要“当前”有效,即与“自我”的有效期相同,该有效期就有效。
在Rust书籍或其他文档中没有发现任何可以帮助我弄清这种情况的东西。
P.S。抱歉,如果我要屠宰术语,那么我对Rust还是很陌生。 谢谢
答案 0 :(得分:3)
您还不能。这将需要generic associated types (GATs)。到今天为止,它仍然只是RFC。
当前的Iterator
/ Stream
API有时被称为“分离”:
这个想法是由
Item
返回的Stream
与self
是“分离的”,这意味着它可以独立于self
进行存储和移动。
假设,GAT登陆后,人们将可以编写如下内容:
trait AttachedStream {
type Item<'s> where Self: 's;
// note the `'s` here!
fn poll_next<'s>(
self: Pin<&'s mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item<'s>>>;
// ^^^^
// `'s` is the lifetime of the `self` reference.
// Thus, the `Item` that gets returned may
// borrow from `self`.
}
这正是您想要的。查看Niko's async interview #2了解更多有趣的细节。
答案 1 :(得分:2)
在定义类型&mut self
时,next
中Item
上的生存期不在范围内,因此Item
不能依赖于该生存期。相反,通常有ThingIterator
持有引用而不是拥有的数据。如果仍然有一个拥有数据的结构,则可能会为IntoIterator
实现&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());
}
另请参见
P.S。您要查找的单词是“已消除”。