在rust中,引用的意思的一個內存地址上數據用一個變量名來表示,而且只能有一個變量名同時有該內存上數據的所有權。如果直接使用=
,那么不是復制,而是發生了內存所有權的轉移,代碼實例:
fn main() {let s1 = String::from("hello world !");println!("s1 = {}", s1);let s2 = s1; // s1的所有權轉移給s2了,此時不能再用s1了println!("s2 = {}", s2);
}
這種方式保證了任意時刻,每個內存地址塊只有全局唯一一個所有權。這種方式存在一個缺陷,如果我們想在函數中使用一個堆內存上數據作為參數,那么參數會發生所有權轉移,當函數結束時,對應的數據會被釋放掉了,給出一個代碼例子:
fn foo(s: String) {println!("foo s = {}", s);
}fn main() {let s = String::from("hello world !");foo(s);
// println!("s = {}", s); // 報錯,因為所有權已經被轉移到函數參數中了
}
上述情況,我們只是想要借用下s
的值,那么“借用”這個概念就是如此,僅僅獲取內存上的值,但是不獲取對應的所有權,內存模型如下:
在rust中借助符號&
實現,代碼實例:
fn foo(s: &String) {println!("foo s = {}", s);
}fn main() {let s = String::from("hello world !");foo(&s);println!("s = {}", s); // 這里是正確的,所有權還在
}
注意:借用的變量在第一次使用之后就失效了,除非重新借用! 給出代碼實例:
fn main() {let s = String::from("hello world !");let s1 = &s;println!("{}", s1); // 正確,執行完成后不再借用
// println!("{}", s1); // 錯誤,已經沒了借用權了
}
對于可變引用來說,也是同樣的道理。不過需要注意的是,可變引用一旦出現在作用域內,就不能其它的引用了。可以通過可變引用修改原來的值。但是,可變引用函數和可變引用可以同時出現,具體看下面的代碼:
fn foo(s: &mut String) {s.push_str(" ---test");println!("foo s = {}", s);
}fn main() {let mut s = String::from("hello world !");let s1 = &mut s; // 可變引用s1.push_str(" ---test");println!("s = {}", s1);foo(&mut s); // 注意聲明方式
}
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态