3

借用した関数がHashMapあり、キーで値にアクセスする必要があります。キーと値が値ではなく参照によって取得されるのはなぜですか?

私の簡略化されたコード:

fn print_found_so(ids: &Vec<i32>, file_ids: &HashMap<u16, String>) {
    for pos in ids {
        let whatever: u16 = *pos as u16;
        let last_string: &String = file_ids.get(&whatever).unwrap();

        println!("found: {:?}", last_string);
    }
}
  • file_ids.get(&whatever).unwrap()の代わりに、参照としてキーを指定する必要があるのはなぜfile_ids.get(whatever).unwrap()ですか?

  • 私が理解しているように、所有しているコレクションが借用されているため、 は借用された stringを意味するlast_stringtype でなければなりません。そうですか?&String

  • 上記の点と同様に、から借用した値を取得するため、 がpos型であると仮定するのは正しいですか?&u16ids

4

3 に答える 3

9

パラメータを参照または値として渡すセマンティクスについて考えてみましょう。

  • 参考:名義変更なし。呼び出された関数は、単にパラメーターを借用します。

  • 値として: 呼び出された関数はパラメーターの所有権を取得し、呼び出し元はそれ以上使用できません。

関数HashMap::getは要素を見つけるためにキーの所有権を必要としないため、より制限の少ない引き渡し方法が選択されました: 参照渡しです。

また、要素の値は返さず、参照のみを返します。値が返された場合、 内の値はHashMapによって所有されなくなりHashMap、今後はアクセスできなくなります。

于 2016-06-09T08:14:47.433 に答える
4

TL;DR : Rust は Java ではありません。

Rust には高レベルの構成要素とデータ構造があるかもしれませんが、Rust の指針となる原則の 1 つで示されているように、本質的には低レベルの言語です

その結果、言語とそのライブラリは、不必要なメモリの割り当てなど、余分なコストを可能な限り排除しようとします。

ケース 1: キーを値で受け取る。

キーが の場合String、これは、1 回だけ割り当てられるローカル バッファを使用できるときに、ルックアップごとにメモリを割り当てる (および割り当てを解除する) ことを意味します。

ケース 2: 値で返す。

値で返すということは、次のいずれかを意味します。

  • コンテナからエントリを削除して、ユーザーに渡します
  • コンテナ内のエントリをコピーして、ユーザーに提供します

後者は明らかに非効率的です(コピーは割り当てを意味します)。前者は、ユーザーが値を別の場所に戻したい場合、再度挿入する必要があることを意味します。これは、ルックアップなどを意味し、また非効率的です。

つまり、この場合、値で返すことは非効率的です。

したがって、Rust は、効率に関する限り最も論理的な選択を行い、実用的な場合はいつでも値で渡したり返したりします。

于 2016-06-09T09:48:10.050 に答える
3

キーが の場合は役に立たないようu16に思えますが、 などのより複雑なキーでどのように機能するかを考えてみてStringください。

Stringその場合、キーを値で取得すると、多くの場合、ルックアップごとに新しいキーを割り当てて初期化する必要があり、コストがかかります。

于 2016-06-09T08:55:12.190 に答える