2015-09-14 4 views
5

Rustは、ユーザー定義の構造体に要素のコレクションを格納するいくつかの方法を提供します。構造体は、カスタム寿命指定子、およびスライスへの参照を与えることができます。Vecとスライスの保存の違いは何ですか?

struct Foo<'a> { 
    elements: &'a [i32] 
} 

impl<'a> Foo<'a> { 
    fn new(elements: &'a [i32]) -> Foo<'a> { 
     Foo { elements: elements } 
    } 
} 

それともVecオブジェクトを与えることができます。

struct Bar { 
    elements: Vec<i32> 
} 

impl Bar { 
    fn new(elements: Vec<i32>) -> Bar { 
     Bar { elements: elements } 
    } 
} 

これら二つのアプローチの主な違いは何ですか?

  • 私はBar::new(vec![1, 2, 3, 4, 5])と呼ぶ度にVecを使用してメモリをコピーしますか?
  • Vecの内容は、所有者Barが有効範囲外になると暗黙的に破棄されますか?
  • 渡される構造体の外側で使用されている場合、参照によってスライスを渡すことに関連する危険性はありますか?

答えて

10

Vecは、3つの部分から構成されている:

  1. メモリ
  2. 割り当てられているどのくらいのメモリの数のチャンクへのポインタ(容量
  3. の数をカウントしいくつのアイテムが格納されているか(サイズ

スライスは二つの部分から構成されています。あなたはのいずれかを移動するたびに

  1. メモリ
  2. 保存されているどのように多くの項目の数(サイズ

のチャンクへのポインタこれらのフィールドはすべてコピーされます。あなたが推測しているように、それはかなり軽量です。ヒープ上の実際のメモリチャンクはコピーも移動もされません。

Vecはメモリの所有権を示し、スライスはメモリの借用を示します。 Vecは、それ自体が割り当て解除されたときにすべてのアイテムとメモリのチャンクを解放する必要があります(はRust-speakでが落ちました)。これは範囲外になったときに発生します。スライスは、ドロップされても何もしません。

スライスを使用する危険性はありません。その理由は、Rust の寿命がであるためです。これらは、決してが無効にされた後に参照を使用することを確認します。

+0

各タイプの内訳は非常に分かりやすいです。 – KChaloux

関連する問題