17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RustでVec<T>に&を付けると&[T]が得られる理由、及びDerefの解説

Last updated at Posted at 2018-05-23

Rustで&[T]を必要とする場所に&vの形でVec<T>を渡すと&[T]に変換されます。
私は最初RustがVec<T>を特別扱いしているのだと思っていたのですが、そうではありません。
これはDerefトレイトの動作です。

Derefは次のように定義されています。

pub trait Deref {
    type Target: ?Sized;
    fn deref(&self) -> &Self::Target;
}

自分への参照をTargetへの参照に変換するというメソッドが定義されています。

また、Derefのドキュメントには次のように書かれています。

If T implements Deref<Target = U>, and x is a value of type T, then:

In immutable contexts, *x (where T is neither a reference nor a raw pointer) is equivalent to *Deref::deref(&x).
Values of type &T are coerced to values of type &U
T implicitly implements all the (immutable) methods of the type U.

これを翻訳すると:

TDeref<Target = U>を実装し、xT型の値のとき:

  • イミュータブルの文脈では、*xは (Tが参照でも生ポインタでもないとき) *Deref::deref(&x)と同値。
  • &T型の値は&U型の値に強制される。
  • Tは型Uの全ての(イミュータブルな)メソッドを暗黙的に実装する。

となります。

つまり冒頭の疑問の答えは、Vec<T>Target = [T]としてDerefを実装しているのでドキュメントの二つ目の項目に当てはまり、コンパイラが自動的にスライスへの参照に変換してくれるからということになります。

他にもiterなどのメソッドはVecのメソッドではなくsliceのメソッドで、三つ目のルールからv.iter()というのはv.deref().iter()に自動的に変換されています。

ミュータブル版のDerefMutもあります。

17
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?