min*_*ree 4 iterator reference mutable lifetime rust
这个问题是相关的,但是它更涵盖了为什么编译器在从 返回可变引用时无法推断安全生命周期的原因Iterator::next,我想我理解。
我的问题是:
在设计自己的迭代器以生成可变引用时,您可以采取哪些具体步骤?最终,我希望有一个尽可能简洁、分步、注释的示例,说明 aIterator及其next实现,当他们遇到这种情况时,我(和任何人)可以将其作为明确的参考。unsafe例子很好,我想它们可能是必要的!
注意:我知道这MutItems通常是推荐的示例,但是它的实现可能很难遵循,因为没有关于 1. 标记在那种情况下如何工作以及 2.iterator!宏扩展到什么以及它如何工作的任何文档。如果你用MutItems你的例子,你能澄清这些事情吗?
这是一种在假设Point结构上拥有可变迭代器的方法。我发现以类似的方式注释每个块非常有用unsafe,因为如果我弄错了,我只会在脚下射击!
Rust 编译器不知道每次推进迭代器时都会得到不同的可变引用。这个unsafe块是安全的,因为程序员保证这个迭代器永远不会返回相同的可变引用两次,或者允许任何其他方式到达同一个地址。
#[derive(Debug)]
struct Point {
x: u8,
y: u8,
z: u8,
}
impl Point {
fn iter_mut(&mut self) -> IterMut {
IterMut {
point: self,
idx: 0,
}
}
}
struct IterMut<'a> {
point: &'a mut Point,
idx: u8,
}
impl<'a> Iterator for IterMut<'a> {
type Item = &'a mut u8;
fn next(&mut self) -> Option<&'a mut u8> {
let retval = match self.idx {
0 => &mut self.point.x,
1 => &mut self.point.y,
2 => &mut self.point.z,
_ => return None,
};
self.idx += 1;
// I copied this code from Stack Overflow without paying attention to
// the prose which described why this code is actually safe.
unsafe { Some(&mut *(retval as *mut u8)) }
}
}
fn main() {
let mut p1 = Point { x: 1, y: 2, z: 3 };
for x in p1.iter_mut() {
*x += 1;
}
println!("{:?}", p1);
}
Run Code Online (Sandbox Code Playgroud)
也可以看看