Rc,RefCell和Box组合的Newtype模式

时间:2015-05-15 07:07:46

标签: rust

因为我不想一次又一次地输入像Rc::new(RefCell::new(Box::new(MyType::new(args...))))这样的代码, 我决定创建新类型RcRefBox,如下所示:

use std::rc::Rc;
use std::cell::RefCell;

struct RcRefBox<T>(Rc<RefCell<Box<T>>>);

impl<T> RcRefBox<T> {
    fn new(value: Box<T>) -> RcRefBox<T> {
        RcRefBox(Rc::new(RefCell::new(value)))
    }
}

trait Interface {}

struct A;
impl Interface for A {}

fn main() {
    let iface: RcRefBox<Interface> = RcRefBox::new(Box::new(A));
}

代码无法使用以下错误进行编译: (婴儿围栏:http://is.gd/ITiR8Q

<anon>:19:16: 19:35 error: the trait `core::marker::Sized` is not implemented for the type `Interface` [E0277]
<anon>:19     let iface: RcRefBox<Interface> = RcRefBox::new(Box::new(A));
                         ^~~~~~~~~~~~~~~~~~~
<anon>:19:16: 19:35 note: `Interface` does not have a constant size known at compile-time
<anon>:19     let iface: RcRefBox<Interface> = RcRefBox::new(Box::new(A));
                     ^~~~~~~~~~~~~~~~~~~
<anon>:19:38: 19:51 error: the trait `core::marker::Sized` is not implemented for the type `Interface` [E0277]
<anon>:19     let iface: RcRefBox<Interface> = RcRefBox::new(Box::new(A));
                                               ^~~~~~~~~~~~~
<anon>:19:38: 19:51 note: `Interface` does not have a constant size known at compile-time
<anon>:19     let iface: RcRefBox<Interface> = RcRefBox::new(Box::new(A));
                                               ^~~~~~~~~~~~~
error: aborting due to 2 previous errors

如何修复这些错误?

1 个答案:

答案 0 :(得分:2)

问题不在于您的struct本身,而在于您传递的trait

Trait对象是动态大小的对象(不实现Sized)。

通常,当您在泛型类型(此处为T)上指定边界时,您会对其进行约束,但是当引入Sized时,确定将应用为默认值绑定,因为大多数通用代码处理Sized类型而结果T仅代表T: Sized

有一个特殊的&#34;扩大&#34;必然会说&#34; T可能不是Sized&#34;:?Sized,如果您希望能够获取trait个对象,则必须申请。将其添加到您的代码中:

use std::rc::Rc;
use std::cell::RefCell;

struct RcRefBox<T: ?Sized>(Rc<RefCell<Box<T>>>);  // ?Sized

impl<T: ?Sized> RcRefBox<T> {                     // ?Sized
    fn new(value: Box<T>) -> RcRefBox<T> {
        RcRefBox(Rc::new(RefCell::new(value)))
    }
}

trait Interface {}

struct A;
impl Interface for A {}

fn main() {
    let iface: RcRefBox<Interface> = RcRefBox::new(Box::new(A));
}

使其有效(http://is.gd/pSZKK2)。