為什么不需要將此堆棧變量移入閉包?

問題描述 投票:1回答:2

我想理解為什么下面的示例中的外部堆棧變量data不需要move關鍵字與閉包一起使用。

該示例取自,表示write_function的生存期取自transfer變量,因此,閉包可以訪問堆棧變量data而無需移動它。

這里是文檔的引言:

請注意,此函數的生命周期是靜態的,但這通常過于嚴格。要使用堆棧數據,請考慮調用傳輸方法捕鱼游戏能赚钱的捕鱼游戏能赚钱的,然后使用write_function來配置可以引用堆棧本地數據的回調。

參見:

use curl::easy::Easy;
let mut data = Vec::new();
let mut handle = Easy::new();
handle.url("/imgs/357962d8b807af399f26c1c38ebf7319").unwrap();
{
    let mut transfer = handle.transfer();
    transfer.write_function(|new_data| {
        data.extend_from_slice(new_data);
        Ok(new_data.len())
    }).unwrap();
    transfer.perform().unwrap();
}
println!("{:?}", data);

為什么這樣做?

或者,如果我嘗試直接使用write_function中的handle,則會出現data被移動的借用錯誤。

這里是一個不起作用的示例捕鱼游戏能赚钱的,我理解為什么它不起作用。我很困惑為什么上面的方法可以代替。

use curl::easy::Easy;
let mut data = Vec::new();
let mut handle = Easy::new();
handle.url("/imgs/357962d8b807af399f26c1c38ebf7319").unwrap();
handle.write_function(move |new_data| {
   data.extend_from_slice(new_data);
   Ok(new_data.len())
}).unwrap();
handle.perform().unwrap();
println!("{:?}", data);
//               ^^^^ error because it was moved
curl rust
2個回答
1
投票

在您的第一個示例中,銹使&mut data穿過堆棧,并繼續讓<main>擁有data

[在您的第二個示例中,銹通過handle.write_function(move |new_data| {關鍵字賦予data所有權move,然后內部將其寫入data,并放在范圍}).unwrap();的末尾,然后在底部試圖通過data再次讀取println!,它要求rust檢索您已經要求將其刪除的內容。


0
投票

您引用的curl文檔來自curl::easy::Easy::write_function方法。如前所述,此函數采用一個閉包,閉包的生存期為'static-換句話說,它必須在程序的整個過程中持續有效。

這意味著此類閉包借用的任何值都永遠不會返回,因為閉包永遠不會超出范圍。

這與curl rust庫包裝了curl C庫這一事實有關,并且C庫的工作原理是允許調用者為各種事件注冊回調函數。在將閉包作為回調函數傳遞給C庫之后,rust編譯器無法跟蹤其有效期,因此,唯一可使用的安全有效期為'static

[要解決此問題,curl模塊提供了一個對象,您可以向其注冊壽命少于Transfer的閉包。 'static對象負責在基礎C庫中注冊和注銷回調,同時注意其生命周期。

了解了這一點,請考慮您的示例代碼:

Transfer

此處,閉包可變地借入{ let mut transfer = handle.transfer(); transfer.write_function(|new_data| { data.extend_from_slice(new_data); Ok(new_data.len()) }).unwrap(); transfer.perform().unwrap(); } 。閉包將傳遞給data,這要求它持續到傳輸對象本身為止。因此,將借用transfer.write_function直到聲明了data的塊的末尾。


推薦問答