頭條地址:https://www.ixigua.com/i676544267458235648...
B站地址:https://www.bilibili.com/video/av78062009?...
網易雲課堂地址:https://study.163.com/course/introduction....
1、例子:
fn main() {
let s1 = gives_ownership(); // gives_ownership 將返回值移給 s1
let s2 = String::from("hello"); // s2 進入作用域
let s3 = takes_and_gives_back(s2); // s2 被移動到takes_and_gives_back 中, 它也將返回值移給 s3
} // 這裡, s3 移出作用域並被丟棄。s2 也移出作用域,但已被移走,
// 所以什麼也不會發生。s1 移出作用域並被丟棄
fn gives_ownership() -> String { // gives_ownership 將返回值移動給呼叫它的函式
let some_string = String::from("hello"); // some_string 進入作用域.
some_string // 返回 some_string 並移出給呼叫的函式
}
// takes_and_gives_back 將傳入字串並返回該值
fn takes_and_gives_back(a_string: String) -> String { // a_string 進入作用域
a_string // 返回 a_string 並移出給呼叫的函式
}
移動來移動去的很麻煩,可能我只是想使用,怎麼辦?
2、引用
例子
fn calculate_length(s: &String) -> usize { // s 是對 String 的引用
s.len()
} // 這裡,s 離開了作用域。但因為它並不擁有引用值的所有權,
// 所以什麼也不會發生
{
let s1 = String::from("hello");
let len = calculate_length(&s1);
}
&s1 語法讓我們建立一個 指向 值 s1 的引用,但是並不擁有它。因為並不擁有這個值,當引用離開作用域時其指向的值也不會被丟棄。
3、借用
要修改的時候,就需要借用
fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
值得注意的是:也不能在擁有不可變引用的同時擁有可變引用。
例子:
let mut s = String::from("hello");
let r1 = &s; // 沒問題
let r2 = &s; // 沒問題
let r3 = &mut s; // 大問題
println!("{}, {}, and {}", r1, r2, r3); //r2、r1不希望在使用時被改變,因此此處error
以下是ok的,例子:
let mut s = String::from("hello");
let r1 = &s; // 沒問題
let r2 = &s; // 沒問題
println!("{} and {}", r1, r2);
// 此位置之後 r1 和 r2 不再使用
let r3 = &mut s; // 沒問題
println!("{}", r3);
4、懸垂引用error
fn main() {
let reference_to_nothing = dangle();
}
fn dangle() -> &String {
let s = String::from("hello");
&s //error,正確的方式是返回s
}
5、總結:
(1)在任意給定時間,要麼 只能有一個可變引用,要麼 只能有多個不可變引用。
(2)引用必須總是有效。