# 變量按存儲位置可以分:靜態變量,堆變量 和棧變量,。
# 靜態變量只能是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來統一管理