簡體   English   中英

為什么在Rust中允許返回當前函數擁有的引用?

[英]Why returning a reference owned by the current function is allowed in Rust?

我正在學習Rust的壽命/所有權概念,並想解釋一下Rust(rustc 1.37.0)中的以下行為。

對於這樣的程序:

#[derive(Debug)]
struct Book {
    price: i32,
}

fn main() {
    let book1 = Book {price: 12};
    let cheaper_book = choose_cheaper(&book1);
    println!("{:?}", cheaper_book);
}

fn choose_cheaper(b1: &Book) -> &Book {
    if b1.price < 15 {
        b1
    } else {
        let cheapest_book = Book {price: 0};
        &cheapest_book
    }
}

銹報告:

17 |   &cheapest_book
   |   ^^^^^^^^^^^^^^ returns a reference to data owned by the current function

而且我可以理解此錯誤,這是因為變量cheapest_book是價格為0的Book的所有者,並且它將在此函數結束時刪除,因此返回的引用在此之后將變為無效。 但是,對於我來說,很難解釋為什么如果將choose_cheaper函數更改為以下內容,為什么允許以下操作:

fn choose_cheaper(b1: &Book) -> &Book {
    if b1.price < 15 {
        b1
    } else {
        let cheapest_book = &Book {price: 0};
        cheapest_book
    }
}

可以給我一些啟示嗎? 謝謝。

在這一行中, let cheapest_book = &Book {price: 0}; ,則Book 不是 Book類型的“新”實例。 每次調用此函數時,它都會返回對相同 Book類型實例的引用,該引用將存儲在可執行文件的只讀數據部分(或者,如果包含CellAtomicUsize或從技術上講,則存儲在該數據部分)類似)。

在這種情況下,我們可以將代碼“擴展”為更明確的內容:

static GLOBAL_BOOK: Book = Book { price: 0 };

fn choose_cheaper<'a>(b1: &'a Book) -> &'a Book {
    if b1.price < 15 {
        b1
    } else {
        let cheapest_book = &GLOBAL_BOOK;
        cheapest_book
    }
}

請注意,對GLOBAL_BOOK的引用實際上可以是&'static Book ,但&'a Book&'a Book的超類型,因此可以將靜態引用當作是'a引用來返回。

如果這看起來很奇怪,請考慮一下這正是字符串文字所發生的; 它們只是沒有顯式&字符: let foo = "string!"; foo&'static str引用可執行文件的只讀部分中的某些數據,而不是本地對象。 這樣您還可以編寫return "string!"; 在函數返回&'a str為任何'a

生銹是否進行此轉換的規則是您“構造”對象時(使用元組語法,結構或枚舉或聯合初始化語法,數字或字符串文字或它們的任意組合- 而不是new()函數調用或&后面的任何其他函數),它們將成為匿名靜態變量。 所以其實&&1_u32'static參考靜態'static參考靜態u32

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM