Function trait_object

Source
pub fn trait_object()
Expand description

§trait 对象本质

示例 1:

    struct CloningLab {
        subjects: Vec<Box<Mammal>>,
        // subjects: Vec<Box<Mammal + Clone>>,
    }

    trait Mammal {
        fn walk(&self);
        fn run(&self);
    }

    #[derive(Clone)]
    struct Cat {
        meow_factor: u8,
        purr_factor: u8
    }

    impl Mammal for Cat {
        fn walk(&self) {
            println!("Cat::walk");
        }
        fn run(&self) {
            println!("Cat::run")
        }
    }

示例2:


    #![allow(unused)]
    #![feature(raw)]

    use std::{mem, raw};

    // an example trait
    trait Foo {
        fn bar(&self) -> i32;
    }

    impl Foo for i32 {
        fn bar(&self) -> i32 {
            *self + 1
        }
    }

    fn main() {
        let value: i32 = 123;

        // let the compiler make a trait object
        let object: &dyn Foo = &value;

        // look at the raw representation
        let raw_object: raw::TraitObject = unsafe { mem::transmute(object) };

        // the data pointer is the address of `value`
        assert_eq!(raw_object.data as *const i32, &value as *const _);

        let other_value: i32 = 456;

        // construct a new object, pointing to a different `i32`, being
        // careful to use the `i32` vtable from `object`
        let synthesized: &dyn Foo = unsafe {
            mem::transmute(raw::TraitObject {
                data: &other_value as *const _ as *mut (),
                vtable: raw_object.vtable,
            })
        };

        // it should work just as if we had constructed a trait object out of
        // `other_value` directly
        assert_eq!(synthesized.bar(), 457);
    }

正常 trait Object 布局图:


                                                           cat's vtable
Cat Layout                     Trait Object
+------------+              +--------------+             +---------------+
|            |              |              |             |               |
|            |              |              |     +-----> | drop pointer  |
| meow_factor|              |              |     |       |    size       |
|            +<--------------+data pointer |     |       |    align      |
| purr_factor|              |              |     |       |               |
|            |              | vtable pointer-----+       | run fn pointer|
|            |              |              |             |walk fn pointer|
|            |              |              |             |               |
+------------+              +--------------+             |               |
                                                         |               |
                                                         |               |
                                                         |               |
                                                         +---------------+

假设:trait Mammal + Clone 布局图:

注意:非法


                                                                  Mammal
                                                           cat's vtable
Cat Layout                     Trait Object
+------------+              +--------------+             +---------------+
|            |              |              |             |               |
|            |              |              |     +-----> | drop pointer  |
| meow_factor|              |              |     |       |    size       |
|            +<--------------+data pointer |     |       |    align      |
| purr_factor|              |              |     |       |               |
|            |              | vtable pointer-----+       | run fn pointer|
|            |              |              |             |walk fn pointer|
|            |              |              +-----+       |               |
+------------+              +--------------+     |       |               |
                                                 |       |               |
                                                 |       |               |
                                                 |       |               |
                                                 |       +---------------+
                                                 |
                                                 |
                                                 |           Clone Vtable
                                                 |
                                                 +-----> +--------------+
                                                         |              |
                                                         | drop pointe  |
                                                         |              |
                                                         | size         |
                                                         | align        |
                                                         |              |
                                                         |  clone       |
                                                         |  fn pointer  |
                                                         |              |
                                                         +--------------+

假设:trait 继承(`trait MammalClone: Mammal+Clone`)布局图:

注意:非法

                                                            MammalClone
                                                           cat's vtable
Cat Layout                     Trait Object
+------------+              +--------------+             +-----------------+
|            |              |              |             |                 |
|            |              |              |     +-----> | drop pointer    |
| meow_factor|              |              |     |       |    size         |
|            +<--------------+data pointer |     |       |    align        |
| purr_factor|              |              |     |       |                 |
|            |              | vtable pointer-----+       | run fn pointer  |
|            |              |              |             |walk fn pointer  |
|            |              |              |             |                 |
+------------+              +--------------+             |clone fn pointer |
                                                         |                 |
                                                         |                 |
                                                         |                 |
                                                         +-----------------+