Rc、RefCell 和 Box 组合的新型模式
Newtype pattern of the combinations of Rc, RefCell and Box
因为我不想一遍又一遍地输入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
如何修复这些错误?
问题不在于你的 struct
本身,而在于你通过的 trait
。
特征对象是动态大小的对象(不实现 Sized
)。
通常,当您指定泛型类型的边界时(T
此处),您会限制它,但是当引入 Sized
时,决定应用它 作为默认边界 因为大多数通用代码处理 Sized
类型,结果 T
单独意味着 T: Sized
.
有一个特殊的 "widening" 绑定说“T
可能不是 Sized
”:?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)。
因为我不想一遍又一遍地输入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
如何修复这些错误?
问题不在于你的 struct
本身,而在于你通过的 trait
。
特征对象是动态大小的对象(不实现 Sized
)。
通常,当您指定泛型类型的边界时(T
此处),您会限制它,但是当引入 Sized
时,决定应用它 作为默认边界 因为大多数通用代码处理 Sized
类型,结果 T
单独意味着 T: Sized
.
有一个特殊的 "widening" 绑定说“T
可能不是 Sized
”:?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)。