目的
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]
参照カウンタの値で挙動が変わるらしい。