#clone #trait-object #traits #cloning #pointers #fat #layout

nightly clone-into-box

用于克隆特质对象的库

1 个不稳定版本

0.1.0 2019年10月13日

#2508 in Rust模式

MIT/Apache

11KB
103

Build Status

用于克隆特质对象的库。

不稳定性

该库依赖于fat指针布局的未记录细节。

因此,这个库被有意标记为不稳定。

示例

创建可克隆的用户定义特质

use clone_into_box::{CloneIntoBox, CloneIntoBoxExt};

// Make the trait a subtrait of `CloneIntoBox`
pub trait MyTrait: CloneIntoBox {
    fn hello(&self) -> String;
}

// Manually implement `Clone` using `clone_into_box`
impl Clone for Box<dyn MyTrait + '_> {
    fn clone(&self) -> Self {
        // Use (**self) to prevent ambiguity.
        // Otherwise you may run into a mysterious stack overflow.
        (**self).clone_into_box()
    }
}

#[derive(Debug, Clone)]
struct Foo(String);

impl MyTrait for Foo {
    fn hello(&self) -> String {
        format!("Hello, {}!", self.0)
    }
}

fn main() {
    let x: Box<dyn MyTrait> = Box::new(Foo(String::from("John")));
    assert_eq!(x.hello(), "Hello, John!");
    let y = x.clone();
    assert_eq!(y.hello(), "Hello, John!");
}

创建现有特质的可克隆变体

use clone_into_box::{CloneIntoBox, CloneIntoBoxExt};

// Use a "new trait" pattern to create a trait for `ExistingTrait + CloneIntoBox`
pub trait FnClone: Fn() -> String + CloneIntoBox {}
impl<T: Fn() -> String + CloneIntoBox + ?Sized> FnClone for T {}

// Manually implement `Clone` using `clone_into_box`
impl Clone for Box<dyn FnClone + '_> {
    fn clone(&self) -> Self {
        // Use (**self) to prevent ambiguity.
        // Otherwise you may run into a mysterious stack overflow.
        (**self).clone_into_box()
    }
}

fn main() {
    let name = String::from("John");
    let x: Box<dyn FnClone> = Box::new(move || format!("Hello, {}!", name));
    assert_eq!(x(), "Hello, John!");
    let y = x.clone();
    assert_eq!(y(), "Hello, John!");
}

无运行时依赖