rust货轮什么时候出现_Rust 学习-什么时候将数据放到堆

什么时候将数据放到堆

认识所有权, 生命周期与引用有效性, 智能指针 这三章是相关联的,所有权和生命周期确保数据的有效性,智能指针数据存放在堆上,指针在栈上。

书中建议

当有一个在编译时未知大小的类型,而又想要在需要确切大小的上下文中使用这个类型值的时候

当有大量数据并希望在确保数据不被拷贝的情况下转移所有权的时候

当希望拥有一个值并只关心它的类型是否实现了特定 trait 而不是其具体类型的时候

个人理解如果是用户自定义结构体数据数据较大或者在运行时才能确定大小的数据,多个不同作用域需要共享数据时建议放在堆中。Vec中的数据就是放在堆中。

使用场景

使用Rust开发一个小工具时,发现经常有调用clone方法的场景。在读取文件数据解析创建了一个结构体,然后放到一个Vec中,在某个地方需要获取一些数据修改一些值,然后保持到另一个Vec中。这时在Vec中取出了值修改数据,clone一份保存,虽然到了需求。但是我想的是两个Vec都是同一份数据,只是两个Vec数量不一样,这时就需要将对象保持到堆中了。

// 场景 多个 C 对象需要共享 A, B 数据,对A需要有修改权限

use std::cell::RefCell;

use std::rc::Rc;

#[derive(Debug)]

struct A {

name: String,

}

impl Drop for A {

fn drop(&mut self) {

println!("A drop: {}", self.name);

}

}

impl Drop for B {

fn drop(&mut self) {

println!("B drop: {}", self.name);

}

}

#[derive(Debug)]

struct B {

name: String,

}

#[derive(Debug)]

struct C {

list_a: Vec>>,

list_b: Vec>,

}

#[test]

fn test_rc() {

let mut c = C {

list_a: Vec::new(),

list_b: Vec::new(),

};

let a = Rc::new(RefCell::new(A {

name: String::from("zhang"),

}));

let b = Rc::new(B {

name: String::from("wu"),

});

println!("a ptr: {:p}", a);

println!("b ptr: {:p}", b);

c.list_a.push(a);

c.list_b.push(b);

f2(&c);

c.list_b.push(Rc::new(B {

name: String::from("li"),

}));

println!("{:?}", c);

}

fn f2(c: &C) {

let mut c2 = C {

list_a: Vec::new(),

list_b: Vec::new(),

};

for c1a in c.list_a.iter() {

println!("a ptr: {:p}", *c1a);

let mut a = (*c1a).borrow_mut();

a.name = String::from("我改了");

c2.list_a.push(Rc::clone(c1a));

}

for c1b in c.list_b.iter() {

println!("b ptr: {:p}", *c1b);

c2.list_b.push(Rc::clone(c1b));

}

println!("{:?}", c2);

}

上面代码两个 C都指向了堆上的A和B,在f2中修改C中的A数据,并将指针放入了第二个C中。在代码的运行结果可以发现A和B都没有clone的动作,两个C对象都是指向的同一份数据。这里的数据不支持多线共享,需要在多线程下共享数据需要使用到Mutex和Arc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值