2017-07-17 35 views
4

我發現這個鏽代碼從stdin得到一個行:如果不使用返回值,`unwrap()`的目的是什麼?

use std::io; 

fn main() { 
    let mut line = String::new(); 
    io::stdin().read_line(&mut line).unwrap(); 
    println!("Input: {}", line); 
} 

io::stdin().read_line(&mut line)line變量設置爲從stdin讀取一行。根據我的理解,read_line()返回一個Result的值,它可以是模式匹配的,或者如果它不是Err,則可以使用.unwrap()來獲得內部值。

但是,從不使用返回值read_line()。僅使用line字符串變量,但即使未使用,大多數時間人們也會使用.unwrap()

如果不使用返回值,unwrap()的用途是什麼?只是要拋出一個錯誤?

回答

10

什麼是unwrap()目的如果不使用返回值?只是要拋出一個錯誤?

是的,但那不是全部

忽略潛在的錯誤是不好的;空的lineline之間的差異很大,因爲錯誤而未被讀取。例如在shell中的典型「管道」命令中,程序需要在停止接收輸入時停止,否則用戶必須將其終止。

在C中,忽略錯誤太容易了。許多語言通過有例外來解決這個問題,但Rust並沒有。

爲了避免這個問題困擾着,它是太容易忘記檢查返回代碼的C程序,一般防鏽功能將捆綁在Result預期的返回值和錯誤,讓你檢查它得到返回值。

但是還有一個潛在的問題:如果調用者不關心返回值會怎麼樣?最值得注意的是,當價值爲()時,沒有人真正關心它。

這裏調用了一些編譯器魔法:Result結構標記爲#[must_use]屬性。該屬性使其必須在返回時使用Result執行某些操作。

因此,就你而言,不僅是展現良好,也是「做某件事」並避免編譯警告的最簡單方法。

+0

*有點編譯器的魔力* - 它不限於編譯器,FWIW。任何用戶類型也可以用'#[must_use]'註釋。 – Shepmaster

+1

@Shepmaster:當然,這個屬性本身*是*魔法(我會爭論的是黑魔法)。我的意思是,如果Rust支持線性類型(而不僅僅是仿射類型),它可以在類型系統中「正確地」建模,但是它不會,而是我們有這個小屬性,它使得類型「接近線性」但並非相當」。 –

2

如果您不想「優雅地」處理無法從標準輸入讀取一行(例如,再次嘗試或選擇默認值)的情況,可以使用unwrap()來引發恐慌;它沉默未使用引起的Result警告:

warning: unused result which must be used 
--> src/main.rs:5:5 
    | 
5 |  io::stdin().read_line(&mut line); 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    | 
    = note: #[warn(unused_must_use)] on by default 
相關問題