Too -many-lists学习摘要

 

  • IterMute实现要点难点

...
pub struct List<T> {
    head: Link<T>,
}
​
type Link<T> = Option<Box<Node<T>>>;
​
struct Node<T> {
    elem: T,
    next: Link<T>,
}
...
...
...
pub struct IterMut<'a, T> {
    next: Option<&'a mut Node<T>>,
}
​
//https://rust-unofficial.github.io/too-many-lists/second-iter-mut.html
//IterMut之所以可以工作, 原文给出了2个理由:
//1. 通过take确实保证了&mut型引用的唯一排他性。
//2. https://doc.rust-lang.org/nomicon/borrow-splitting.html
impl<T> List<T> {
    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
        //this works coz: Rust understands that it's ok to shard a mutable reference into the subfields of the pointed-to struct, 
        //because there's no way to "go back up", and they're definitely disjoint.
        IterMut { next: self.head.as_mut().map(|node| &mut **node) }
    }
}
​
impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;
​
    fn next(&mut self) -> Option<Self::Item> {
        self.next.take().map(|node| {//此处next被take收割了, 保证了map外部无法再访问到!从而确保&mut引用排他性。
            //this works coz: Rust understands that it's ok to shard a mutable reference into the subfields of the pointed-to struct,
            // because there's no way to "go back up", and they're definitely disjoint.
            //We take the Option<&mut> so we have exclusive access to the mutable reference. 
            //No need to worry about someone looking at it again.
            self.next = node.next.as_mut().map(|node| &mut **node);
            &mut node.elem
        })
    }
    ...
    ...

上面的IterMute代码之所以可以工作,too-many-lists作者给出两点理由:

  1. 通过take确实保证了&mut型引用的唯一排他性。

  2. Rust知道可以同时借用结构的不相交字段,如下面代码例子。

 

//https://doc.rust-lang.org/nomicon/borrow-splitting.html
//https://rust-unofficial.github.io/too-many-lists/second-iter-mut.html
​
#[derive(Debug)]
struct Foo {
    a: i32,
    b: i32,
    c: i32,
}
​
fn main() {
    let mut x = Foo {a: 0, b: 0, c: 0};
    let xx =&mut x;
    let a = &mut x.a;
    let b = &mut x.b;
    let c = &x.c;
    *b += 1;
    let c2 = &x.c;
    *a += 10;
    println!("{} {} {} {}", a, b, c, c2);
    //println!("whole struct: {:?}", xx);
    //Rust 编译器很聪明,允许你分别持有指向结构体子成员的可变引用,因为Rust编译器知道他们彼此没有交集,是安全的。
    //但是`引用xx`与后续声明的其他引用有交集,很明显struct整体当然包含其子成员!Rust铁律:允许多只读,排他写!所以不安全!
    //但是Rust编译器很聪明,只要`引用xx`无处使用就是安全的!所以注释掉println!就OK, 否则报错:` cannot borrow `x.a` as mutable more than once at a time`
​
}

too-many-lists中亮点很多,非常值得学习的Rust著作, 而IterMute的实现方法更是创意非凡!不用unsafe也可有这么好的trick! 绝对让人眼前一亮!灵光一闪!值得反复学习。例子代码位置:https://github.com/yujinliang/rust_learn/tree/master/too_many_lists

 

 

  • Author

作者:心尘了

email: 285779289@qq.com

git: https://github.com/yujinliang

水平有限,万望海涵,指导

 

 

  • Reference

https://doc.rust-lang.org/nomicon/borrow-splitting.html

https://rust-unofficial.github.io/too-many-lists/second-iter-mut.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值