从您自己的迭代器返回可变引用的简单示例

问题描述 投票:3回答:1

This question是相关的,但是它还涵盖了原因[[why当从Iterator::next返回可变引用时,编译器无法推断安全寿命,我认为我理解。

我的问题是:

设计

own

迭代器以便可以生成可变引用时可以采取哪些具体步骤?最终,我希望有一个Iterator及其next实现的简洁,逐步,评论的示例,我(和任何人)可以在运行时作为明确的参考陷入这种情况。 unsafe例子很好,我想可能是必要的!注意:我知道通常推荐使用MutItems,但是由于没有关于1.标记在这种情况下如何工作以及2. MutItems宏有什么用的文档,因此其实现可能很难遵循。扩展到及其工作方式。如果以iterator!为例,请您澄清以下内容?
reference iterator rust mutable lifetime
1个回答
5
投票
这是在假设的MutItems结构上具有可变迭代器的方法。我发现

非常以类似的方式注释每个Point块很有用,因为如果我弄错了,我只会把自己开枪打死!

Rust编译器不知道每次推进迭代器都会获得不同的可变引用。 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); }
© www.soinside.com 2019 - 2024. All rights reserved.