2016-05-13 13 views
4

JSON文書を読み取るためのserde_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> 

私はアンダースコアがマッチコンテキストで意味することを理解しますが、ジェネリックをインスタンス化するには?それはどういう意味ですか?私は錆の本やリファレンス、ウェブ検索で何の答えも見つけられませんでした。

+0

も参照[Vecと<_>何ですか?](HTTP:

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

これは"turbofish operator"を使用して避けることができるため、多くの場合に特に便利です://stackoverflow.com/q/34363984/155423)。 – Shepmaster

答えて

4

これはプレースホルダです。この文脈では、コンパイラが型を推論するのに十分な情報がないことを意味します。

コンパイラにタイプを推論させるために、コード内でこれを使用できます。たとえば:

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

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:タイプelisionについて興味深い議論があります。いくつかの議論タイプは理解のために必要であり、他のタイプは実際の情報を混乱させる。それは最後に非常に個人的な選択です:) –

+0

あなたは私が議論のどの側面を推測することができます。私が物事の定義に行くことができるまともなIDEを持っていればそれほど悪くないでしょうが、現時点では私の設定ではありません。私はこれを行うことができないテキストエディタとしてAtomを使用しています。私はVisualRustを試しましたが、現時点では絶望的です。 – Zephilim

関連する問題