zoukankan      html  css  js  c++  java
  • Rust 智能指针(二)

    1. Rc<T> 引用计数指针

    Rc<T> 是引用计数指针,可以使用clone使得指针所指向的数据具有多个所有者。

    enum List {
        Cons(i32, Rc<List>),
        Nil,
    }
    
    use List::{Cons, Nil};
    use std::rc::Rc;
    
    fn main() {
        let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
        let b = Cons(3, Rc::clone(&a));
        let c = Cons(4, Rc::clone(&a));
    }
    

    需要注意的是,Rc<T>指针的数据是不可变的

    2. RefCell<T> 内部可变指针

    RefCell<T>指针可以绕过编译期借用检查,普通指针和引用同一时间只能有一个可变引用或者多个不可变引用。而RefCell<T>把这个检查推迟到了运行时。如果有引用违反了借用原则,程序会panic!

    use std::cell::RefCell;
    
    struct S{
        data:i32
    }
    fn main() {
        let s = RefCell::new(S{data:3});
        s.borrow_mut().data=5;
        println!("{}",s.borrow().data);
    }
    

    通过&self.borrow()获得一个不可变借用,&self.borrrow_mut()获得一个可变借用。

    use std::cell::RefCell;
    
    struct S{
        data:i32
    }
    fn main() {
        let s = RefCell::new(S{data:3});
        let s1=s.borrow_mut();
        let s2 = s.borrow_mut();
    }
    

    s有两个可变引用,这很明显违反了引用借用原则。所以运行后会得到一个panic。

    thread 'main' panicked at 'already borrowed: BorrowMutError', srclibcore
    esult.rs:997:5
    stack backtrace:
       0: std::sys_common::backtrace::_print
                 at srclibstdsyswindowsacktrace/mod.rs:95
                 at srclibstdsyswindowsacktrace/mod.rs:82
                 at srclibstdsys_common/backtrace.rs:71
       1: std::panicking::default_hook::{{closure}}
                 at srclibstdsys_common/backtrace.rs:59
                 at srclibstd/panicking.rs:197
       2: std::panicking::default_hook
                 at srclibstd/panicking.rs:211
       3: std::panicking::rust_panic_with_hook
                 at srclibstd/panicking.rs:474
       4: std::panicking::continue_panic_fmt
                 at srclibstd/panicking.rs:381
       5: rust_begin_unwind
                 at srclibstd/panicking.rs:308
       6: core::panicking::panic_fmt
                 at srclibcore/panicking.rs:85
       7: core::result::unwrap_failed
                 at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26esrclibcore/macros.rs:18
       8: core::result::Result<T,E>::expect
                 at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26esrclibcore/result.rs:825
       9: core::cell::RefCell<T>::borrow_mut
                 at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26esrclibcore/cell.rs:873
      10: untitled::main
                 at src/main.rs:9
      11: std::rt::lang_start::{{closure}}
                 at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26esrclibstd/rt.rs:64
      12: std::panicking::try::do_call
                 at srclibstd/rt.rs:49
                 at srclibstd/panicking.rs:293
      13: _rust_maybe_catch_panic
                 at srclibpanic_unwind/lib.rs:87
      14: std::rt::lang_start_internal
                 at srclibstd/panicking.rs:272
                 at srclibstd/panic.rs:388
                 at srclibstd/rt.rs:48
      15: std::rt::lang_start
                 at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26esrclibstd/rt.rs:64
      16: main
      17: _tmainCRTStartup
      18: mainCRTStartup
      19: unit_addrs_search
      20: unit_addrs_search
    

    3.使用Rc<T>和RefCell<T>构建具有多个所有者的可变引用

    use std::cell::RefCell;
    use std::rc::Rc;
    
    
    struct S{
        data:i32
    }
    fn main() {
        let s = Rc::new( RefCell::new(S{data:3}));
        let s1 = Rc::clone(&s);
        s1.borrow_mut().data=43;
        println!("{}",RefCell::borrow(&s).data);
    }
    

    输出43

  • 相关阅读:
    Python中的sorted函数以及operator.itemgetter函数
    a=a+(a++);b=b+(++b);计算顺序,反汇编
    带基虚类的构造函数执行顺序
    开源系统管理资源大合辑
    linux的LNMP架构介绍、MySQL安装、PHP安装
    lamp下mysql安全加固
    ITSS相关的名词解释
    从苦逼到牛逼,详解Linux运维工程师的打怪升级之路
    Linux 文件系统概览
    Exchange2010批量删除邮件
  • 原文地址:https://www.cnblogs.com/ywxt/p/11106563.html
Copyright © 2011-2022 走看看