This question是相关的,但是它还涵盖了原因[[why当从Iterator::next
返回可变引用时,编译器无法推断安全寿命,我认为我理解。
设计
own
迭代器以便可以生成可变引用时可以采取哪些具体步骤?最终,我希望有一个Iterator
及其next
实现的简洁,逐步,评论的示例,我(和任何人)可以在运行时作为明确的参考陷入这种情况。 unsafe
例子很好,我想可能是必要的!注意:我知道通常推荐使用MutItems
,但是由于没有关于1.标记在这种情况下如何工作以及2. MutItems
宏有什么用的文档,因此其实现可能很难遵循。扩展到及其工作方式。如果以iterator!
为例,请您澄清以下内容?MutItems
结构上具有可变迭代器的方法。我发现非常以类似的方式注释每个Point
块很有用,因为如果我弄错了,我只会把自己开枪打死!
unsafe
块是安全的,因为程序员保证该迭代器可以never
返回两次相同的可变引用,或允许任何其他方式到达相同的地址。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);
}