2

Rust では、aは脂肪参照&Tであり、実際には に対応します。Ttraitraw::TraitObject

pub struct TraitObject {
    pub data: *mut (),
    pub vtable: *mut (),
}

を使用すると、余暇に を分解TraitObjectおよび再構築できます。&T

ただし、 a を分解して を取得するvtableのは簡単ですが、そもそも を取得せず、 and だけを取得する&Tとどうなるでしょうか。基本的に、次のようなものです。&TTS

fn make_vptr<T: ?Sized, S>() -> *mut ();

どうすればそこから v-ptr を推測できますか? 私が使用できる組み込みはありますか?

S注: を作成して(または空中から呼び出して)参照を作成する単純な実装は&T機能しません。コンパイラTは、必ずしも a ではないため、traitサイズ&Tが 1 つまたは 2 つのポインターであると不平を言います。

4

2 に答える 2

3

可能性は、マクロを使用して魔法の仕事をすることです:

#![feature(raw)]

macro_rules! make_vptr(
    ($S:ty, $T:ty) => ({
        let s: &$S = unsafe { ::std::mem::uninitialized() };
        let t: &$T = s;
        let r: ::std::raw::TraitObject = unsafe { ::std::mem::transmute(t) };
        r.vtable
    })
);

Tこのコードは、 がトレイトでない場合 (ファット ポインターであることをtransmute(..)確認したため)、またはによって実装されていない場合(代入により)コンパイルされません。&TTS

次に、直接使用できます。

use std::fmt::Display;

fn main() {
    let u32_display_vtable = make_vptr!(u32, Display);

    let x = 42u32;

    let disp: &Display = unsafe {
        ::std::mem::transmute(::std::raw::TraitObject {
            data: &x as *const _ as *mut _,
            vtable: u32_display_vtable,
        })
    };

    println!("{}", disp);
}
于 2015-05-17T16:09:55.150 に答える
0

これが現在可能であるとは思いません。

これが機能するためには、T一般的なパラメーターを制約して、特性のみを受け入れることができる必要があります。これはできません。&Tその結果、 vtable を取得するなど、それが特性であることに依存することを行うことはできません。

于 2015-05-17T16:09:13.263 に答える