本文へ
ハクソク

世界を動かす技術を、日本語で。

RustのVtableを可視化する:dyn Traitがメモリ内でどのように機能するか

元記事: 原文(sofiabelen.github.io)

概要

  • RustとC++のポリモーフィズムの違いを比較・解説
  • 静的ディスパッチ(ジェネリクス/モノモルフィゼーション)と動的ディスパッチ(dyn Trait)の挙動
  • ゼロサイズ型(ZST)やアドレスの扱いの哲学の違い
  • Rustにおけるvtableの管理方法とC++との根本的な違い
  • Vec<Box>による異種型コレクションの実現方法

RustとC++のポリモーフィズム比較

  • C++では 仮想関数 によるランタイムポリモーフィズム、 CRTP によるコンパイル時ポリモーフィズムの2つの主要手法
    • 仮想関数は vtable をオブジェクト内に保持し、自動的に仮想ディスパッチ
    • CRTPはテンプレートによる静的ディスパッチ。可読性は落ちるが実行時コストゼロ
  • Rustでは dyn Trait による動的ディスパッチ、 ジェネリクス(静的ディスパッチ) によるモノモルフィゼーション
    • dyn TraitはC++の仮想関数に近いが、 vtable管理の哲学が異なる

    • RustのジェネリクスはCRTPに近いが、 型制約を明示的に記述 する点が特徴

    • C++: 型制約は暗黙的(duck typing的)

    • Rust: 型制約は明示的(traitの実装宣言)

静的ディスパッチ(ジェネリクス/モノモルフィゼーション)

  • Rustのtraitを用いた静的ディスパッチ例
    • trait Draw { fn draw(&self) -> &str; }
    • impl Draw for Circle, Square などで具象型に実装
    • fn draw_shape<T: Draw>(shape: T) で呼び出し
  • コンパイラが型ごとに draw_shape::, draw_shape:: を生成
  • 静的ディスパッチは 実行時コストゼロ、型がコンパイル時に決定

ゼロサイズ型(Zero-Sized Types: ZST)

  • C++では空のstructも1バイトサイズ保証。 アドレスによる識別
  • Rustでは ゼロサイズ型 は本当にサイズ0。 所有権による識別
    • &a, &bのアドレスはデバッグ時は異なるが、リリースビルドでは同じになる場合あり
    • アドレスの一意性は保証されない
    • 識別は所有権とバインディング名で行う (borrow checkerが管理)
  • Rustの哲学: 「アドレス」ではなく「所有権」で値の一意性を管理

動的ディスパッチ(dyn Trait)

  • &dyn Traitは ワイドポインタ(16バイト) :データポインタ+vtableポインタ
  • vtableは 型×トレイトごとに1つだけ生成 され、オブジェクト自体にはvtable情報を持たせない
  • std::mem::transmuteでポインタの中身を確認可能
  • 同じ型同じTraitならvtableポインタは同一、データポインタはインスタンスごとに異なる

異種型コレクションの実現

  • RustのVecは Tが同一型・同一サイズ である必要
  • Vec<Box>で 異なる型をまとめて格納可能
    • Boxはヒープ上に実体を確保し、ワイドポインタで管理
  • C++のvector<Base*>と似ているが、 vtable管理の場所と哲学が異なる
    • C++はオブジェクト内部にvtableポインタ
    • Rustは 呼び出し側でvtableを選択し、オブジェクト自体は何も知らない

vtableの哲学的違い

  • C++:クラス定義時点で仮想関数かどうか決定、すべてのインスタンスがvtableを持つ
  • Rust: 呼び出し時点で静的/動的ディスパッチを選択、型自体はvtableの存在を意識しない
  • Traitの組み合わせごとにvtableが生成 され、DuckがFly/Swim両方実装してもvtableは別

まとめとRust的思考法

  • RustをC++の別構文と考えるのは 本質を見誤る原因
  • 所有権・型安全・動的ディスパッチの選択の柔軟性 がRustの特徴
  • vtableの管理、ZST、型制約の明示性など、 Rust独自の設計哲学 を理解することが重要
  • 動的ディスパッチが必要となる場面 (異種型コレクション・実行時型不定など)を正しく認識することが、Rustマスターへの第一歩

提供: ハクソク · 要約更新:

AIによる日本語要約です。内容は原文とあわせてご確認ください。

Hacker Newsの議論を読む