Rust 程式設計視訊教程對應講解內容-引用

linghuyichong發表於2019-12-19

頭條地址: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)引用必須總是有效。

令狐一衝

相關文章