# 变量按存储位置可以分:静态变量,堆变量 和栈变量,。
# 静态变量只能是pub 的时候,才能在 unsafe方法中进行修改。
# 栈变量直接进行修改,或者通过可变引用进行修改,或者还可以转化为堆变量进行修改。例如: 下方的Vec相关操作可以换为i32等原始数据类型,再转化为堆变量进行操作。
# 堆变量可以为任何类型;在调用栈和线程中如何修改呢?
1. 直接修改; 当然变量要有mut关键字才能修改。
fn main() {
let mut v =vec![];
v.push(1);
println ! ("Here's vector: {:?}", &v); // Here's vector: [1]
}
2. 通过可变引用修改,
fn main() {
let mut v=vec![];
// &mut v,代替引用的对象可以修改;&v则不可以修改; mut v_ref则代表可以通过v_ref进行对原对象进行修改。原对象如果不可变,则&mut v 编译通不过。
let mut v_ref= &mut v;
//println ! ("Here's vector: {:?}", &v); //此句编译无效,不可变引用和可变引用会引起引用冲突,范围层叠。
v_ref.push(1);
println ! ("Here's vector: {:?}", &v); // Here's vector: [1]
}
3. 通过智能指针访问
fn main() {
unsafe { //v_ref.as_mut和v_ref.as_ref 使用了不安全的代码。
let mut v=vec![];
let mut v_ref= Box::into_raw_non_null(box v);
//println ! ("Here's vector: {:?}", &v); / v已经无效,所有权被移交给boxv_ref 变成一个NonNull<Vec<i32>>
v_ref.as_mut().push(1); //指针转成 Vec<i32>,进行修改
//println ! ("Here's vector: {:?}", &v); // v已经无效,所有权被移交
println ! ("Here's vector: {:?}", v_ref.as_ref()); //Here's vector: [1]
}}
4. 通过闭包进行修改,闭包可以隐匿和显式传入参数进行操作,
fn main() {
let mut v = vec![];
let mut handler=|| {
v.push(1); //传入一个可变的 &mut v
};
handler();
println!("Here's vector: {:?}", &v); // Here's vector: [1]
}
5. 多线程下进行修改变量
use std::thread;
use std::sync::{Arc, mpsc};
fn main() {
let mut v =vec![1, 2, 3];
println ! ("Here's vector: {:?}", &v);
let (tx,rx)=mpsc::channel();
thread::spawn(move || {
v.push(4);
tx.send(v);
});
let and_v=rx.recv();
match and_v {
Ok(t)=>{println ! ("Here's rece vector: {:?}", t);},
Err(_)=>{}
}
}
输出:
Here's vector: [1, 2, 3]
Here's rece vector: [1, 2, 3, 4]
6. 用RefCell 来修改内部变量,Rc只能引用变量次数,Rc::Strong来得到某变量的当前引用次数; 合起来才能修改引用变量的值
use std::cell::RefCell;
use std::rc::Rc;
fn main() {
let mut v = Rc::new(RefCell::new(vec![1, 2, 3]));
let mut cell= Rc::clone(&mut v);
println!("Here's vector: {:?}", &v);
cell.borrow_mut().push(4);
println!("Here's vector: {:?}", &v);
v.borrow_mut().push(5);
println!("Here's vector: {:?}", &cell);
}
输出:
Here's vector: RefCell { value: [1, 2, 3] }
Here's vector: RefCell { value: [1, 2, 3, 4] }
Here's vector: RefCell { value: [1, 2, 3, 4, 5] }
这样使用,多个借用变量可以串插使用,不用在乎 不可变引用和可变引用的范围层叠引起的编译,因为由Rc来统一管理