2016-05-13 236 views
4

雖然與serde_json工作閱讀JSON文檔,我寫了下面的代碼行獲得展開的serde_json::from_str返回值的結果:用下劃線實例化Rust泛型意味着什麼?

fn get_json_content(content_s: &str) -> Option<Value> { 
    let ms: String = serde_json::from_str(content_s).unwrap; // <-- 

    match serde_json::from_str(content_s) { 
     Ok(some_value) => Some(some_value), 
     Err(_) => None 
    } 
} 

正如你所看到的,我忘了()上結束調用unwrap,這就造成了以下錯誤:

error: attempted to take value of method unwrap on type core::result::Result<_, serde_json::error::Error>

let ms: String = serde_json::from_str(content_s).unwrap; 

但是,當我在這看遠一點,那讓我覺得奇怪的事情是:

core::result::Result<_, serde_json::error::Error> 

我明白下劃線在匹配上下文中意味着什麼,但要實例化一個泛型?那麼這是什麼意思?我無法在Rust書籍,參考資料或網頁搜索中找到任何答案。

+0

參見[什麼是VEC <_>?](HTTP ://stackoverflow.com/q/34363984/155423)。 – Shepmaster

回答

4

這是一個佔位符。在這種情況下,這意味着編譯器沒有足夠的信息來推斷類型。

你可以在你的代碼中使用它來讓編譯器推斷出你的類型。例如:

pub fn main() { 
    let letters: Vec<_> = vec!["a", "b", "c"]; // Vec<&str> 
} 

這是因爲在許多情況下,特別方便你可以避免使用"turbofish operator"

fn main() { 
    let bar = [1, 2, 3]; 
    let foos = bar.iter() 
        .map(|x| format!("{}", x)) 
        .collect::<Vec<String>>(); // <-- the turbofish 
} 

VS

fn main() { 
    let bar = [1, 2, 3]; 
    let foos: Vec<_> = bar // <-- specify a type and use '_' to make the compiler 
          //  figure the element type out 
      .iter() 
      .map(|x| format!("{}", x)) 
      .collect(); // <-- no more turbofish 
} 
+0

謝謝你。我更喜歡明確所有類型,因爲省略類型只會讓代碼不可讀,這就是爲什麼我總是在let綁定中指定類型的原因。我知道這在Rust中似乎是一種反模式,但我花了太多時間來弄清楚事物的類型,所以我寧願明確表示。 – Zephilim

+0

@Zephilim:關於type elision有一個有趣的說法;一些爭論類型是理解所必需的,另一些則認爲它們混淆了真實的信息。這是一個非常個人的選擇:) –

+0

那麼你可以猜測我的論點的哪一方面。如果我有一個體面的IDE可以用於定義事物,那麼這並不會那麼糟糕,但那不是我目前的設置。我只是使用Atom作爲無法做到這一點的文本編輯器。我嘗試過VisualRust,但目前這是無望的。 – Zephilim