LoginSignup
13
10

More than 3 years have passed since last update.

RustでRc<RefCell<T>>する

Last updated at Posted at 2019-12-19

目的

RustではRc<RefCell<T>>が使われることが多い。
3段活用みたいなRustコードを1段ずつ書いてみる。

なお、Outputはすべて[1, 2, 3, 4, 5]である。

コード

T

main.cpp
fn append(data:&mut Vec<i32>){
    data.push(4);
}

fn main(){

    let mut data = vec![1,2,3];

    append(&mut data);

    data.push(5);
    println!("{:?}", data);

}

RefCell<T>

main.cpp
use std::cell::RefCell;

fn append(data:&RefCell<Vec<i32>>){
    data.borrow_mut().push(4);
}

fn main(){

    let data = RefCell::new(vec![1,2,3]);

    append(&data);

    data.borrow_mut().push(5);
    println!("{:?}", data.borrow());

}

RC<RefCell<T>>

main.cpp
use std::cell::RefCell;
use std::rc::Rc;

fn append(data:Rc<RefCell<Vec<i32>>>){
    data.borrow_mut().push(4);
}

fn main(){

    let data = Rc::new(RefCell::new(vec![1,2,3]));

    append(Rc::clone(&data));

    data.borrow_mut().push(5);
    println!("{:?}", data.borrow());

}

こういうことはできない

コンパイル通らない例
RcはRead-onlyで使うためのもので、上記RC<RefCell<T>>を使わなければならない

main.rs
use std::rc::Rc;

fn append(Rc<Vec<i32>>){
    data.push(4);
}

fn main(){

    let mut data = Rc::new(vec![1,2,3]);

    append(Rc::clone(&data));

    data.push(5);
    println!("{:?}", data);

}

make_mutはおすすめしない

main.rs
use std::rc::Rc;

fn append(mut data:Rc<Vec<i32>>){
    Rc::make_mut(&mut data).push(4);
    println!("append: {:?}", data);
}

fn main(){

    let mut data = Rc::new(vec![1,2,3]);

    append(Rc::clone(&data));
    println!("main@1 {:?}", data);

    Rc::make_mut(&mut data).push(5);
    println!("main@2 {:?}", data);

    Rc::make_mut(&mut data).push(5);
    println!("main@3 {:?}", data);

}

Output

append: [1, 2, 3, 4]
main@1 [1, 2, 3]
main@2 [1, 2, 3, 5]
main@3 [1, 2, 3, 5, 5]

参照カウンタの値で挙動が変わるらしい。

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10