2016-10-07 6 views
4

を移動せずに私はこれらの構造体を持っている:アクセスネストされた構造

#[derive(Debug, RustcDecodable)] 
struct Config { 
    ssl: Option<SslConfig>, 
} 

#[derive(Debug, RustcDecodable)] 
struct SslConfig { 
    key: Option<String>, 
    cert: Option<String>, 
} 

は、彼らはtomlファイルから充填ます。これは完全に正常に動作します。 Option<T>が入っているので、unwrap()に電話するか、matchに電話する必要があります。

しかし、私は次の操作を実行したい場合:

let cfg: Config = read_config(); // Reads a File, parses it and returns the Config-Struct 
let keypath = cfg.ssl.unwrap().key.unwrap(); 
let certpath = cfg.ssl.unwrap().cert.unwrap(); 

cfg.sslkeypathに移動しますので、それは動作しません。しかし、なぜそれは動かされますか?キーを取得するにはunwrap()sslに電話します(とunwrap())。したがって、key.unwrap()の結果は移動する必要がありますか?

ポイントがありませんか?これらの構造体をこのように(または他のきちんとした方法で)アクセスできるようにするにはどうすればよいでしょうか? #[derive(Debug, RustcDecodable, Copy, Clone)]を実装しようとしましたが、これはCopyStringに実装する必要があるため動作しません。次に、CopyVec<u8>などを実装する必要があります。より便利なソリューションが必要ですか?

答えて

5

Option::unwrapの定義は何ですか? From the documentation

fn unwrap(self) -> T 

それは、その入力(ここではcfg.ssl)を消費。

これは何をしたい、あなたの代わりに(参照、値ではなく)&selfを消費することから始めるであろう、&TOption<T>から行きたいされていない...またはあなたがunwrapを呼び出す前にOptioncloneたい。

クローニングはほとんど解決されていない...ここで代替がas_ref次のとおりです。

fn as_ref(&self) -> Option<&T> 

、したがって、あなたが書くことができます。

let keypath /*: &String*/ = cfg.ssl.as_ref().unwrap().key.as_ref().unwrap(); 
            ^~~~~~~    ^~~~~~~~ 
+1

'cfg.ssl.as_ref()。map(| ssl |&ssl.key).unwrap()'が短く...ここに書き込む方が良いかどうかはわかりません。 –

+0

@LukasKalbertodt:ちょっと複雑に見えます...もちろん、ここでの問題は「解きほぐさず」です。 –

+0

おそらく 'unwrap'の代わりに' as_ref()。and_then() 'を使って最初のアンラップを避けることができますが、* some *ポイントでOptionをアサートするか、エラーを合理的に処理する必要があります。 – LinearZoetrope

3

のでkey.unwrap()の結果が移動しますでしょうか?

はい、それだけではありません。ここでの重要な洞察は、変数getがunwrap()に移動したことです。さんはthe function signatureを見てみましょう:

fn unwrap(self) -> T { ... } 

それはselfをとり、そのオブジェクトが機能に移動です。しかしこれはssl.unwrap()にも当てはまります!

だから、書くとき:

cfg.ssl.unwrap().key.unwrap(); 

あなた先手cfg.sslunwrap()に、あなたはその結果の一つのフィールドにアクセスし、再びunwrap()にそのフィールドを移動します。はい、cfg.sslが移動されました。

let ssl = cfg.ssl.unwrap(); 
let keypath = ssl.key.unwrap(); 
let certpath = ssl.cert.unwrap(); 

それとも、おそらくそうである(移動したくない場合は、as_ref() methodで見ることができます。これを解決するために、あなたはそうのように、最初のunwrap()呼び出しの一時的な結果を保存することができます)。

+0

ありがとうございます。私が持っていた問題を理解するのを助けました! –

関連する問題