簡體   English   中英

何時無法推斷 Rust 借用檢查器的壽命?

[英]When it is not possible to infer the lifetime in the Rust borrow checker?

在大多數情況下,Rust 編譯器可以推斷壽命。 如果生命周期 scope 在運行時確定,則表示必須明確標記生命周期。

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

這里,

  • 生命周期是通用的。
  • 這意味着在返回 function 結果后,有一個 scope 綁定到生命周期 'a。
  • 編譯器可以知道 memory 在最短生命周期內有效的信息'a.

我很好奇。 而不是使用生命周期語法,編譯器不能只采用較少的 scope 區域,生命周期 'a 可以綁定到該區域嗎?

fn main() { //larger scope
    let s1 = String::from("long string is long");

    { //fewer scope
        let s2 = String::from("xyz");
        let result = longest(s1.as_str(), s2.as_str());
        println!("The longest string is {}", result); 
    } 
      
}

即使調用方的調用棧比較復雜,scope 區域是在借用時確定的,所以同樣的問題似乎是可能的。

fn func1<'a>(x: &'a str, y: &'a str) {
   let c = String::from("hello");
   let result = func2 (a,b,c)
   ...
}

我認為您以錯誤的方式處理問題。 在編譯 function (例如您展示的main()時,借用檢查器不會檢查它調用的各個函數的內容,例如 long longest() ,它只檢查它們的簽名 這是一個特性:它允許 function 的實現在不影響其簽名提供的保證的情況下進行更改。 如果main()成功編譯,您可以確定它會繼續編譯,但是只要您不更改其聲明,您修改的longest

在 long longest()的情況下,未注釋的簽名是模棱兩可的:

fn longest(x: &str, y: &str) -> &str

// does the above mean:
fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'a str // returns sub-slice of x
fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'b str // returns sub-slice of y
fn longest<'c>    (x: &'c str, y: &'c str) -> &'c str // returns sub-slice outlived by x and y
fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'static str  // returns static data

如果沒有生命周期注釋,我們無法僅通過查看聲明來判斷返回的&str是來自第一個&str 、第二個&str 、一個共同的生命周期,還是可能來自 static &str 對於非常簡單的函數,比如接受和返回單個引用的函數,編譯器會執行“ 生命周期省略”,它會機械地選擇未注釋簽名的“明顯”解釋,允許您編寫 fnlongest fn longest(x: &str) -> &str作為fn longest<'a>(x: &'a str) -> &'a str的簡單簡寫。 但是當 function 接受多個引用時,編譯器拒絕猜測並讓您拼出您想要的內容。

正如答案開頭所指出的,這常常使初學者感到困惑,編譯器絕對拒絕做的是從 function 主體推斷生命周期簽名,因為這會使簽名依賴於實現。

暫無
暫無

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

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