您如何创建Box< T>当T是特征对象时?
我有以下代码
extern crate rand;
use rand::Rng;
pub struct Randomizer {
rand: Box<Rng>,
}
impl Randomizer {
fn new() -> Self {
let mut r = Box::new(rand::thread_rng()); // works
let mut cr = Randomizer { rand: r };
cr
}
fn with_rng(rng: &Rng) -> Self {
let mut r = Box::new(*rng); // doesn't work
let mut cr = Randomizer { rand: r };
cr
}
}
fn main() {}
它抱怨
error[E0277]: the trait bound `rand::Rng: std::marker::Sized` is not satisfied
--> src/main.rs:16:21
|
16 | let mut r = Box::new(*rng);
| ^^^^^^^^ `rand::Rng` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `rand::Rng`
= note: required by `<std::boxed::Box<T>>::new`
我不明白为什么Box<T>
没有在T
上强加Sized
的原因.
I don't understand why it requires Sized
on Rng
when Box<T>
doesn't impose this on T
.
有关Sized
特征和绑定的更多信息-这是一个相当特殊的特征,即 Box::new
:
More about the Sized
trait and bound - it's a rather special trait, which is implicitly added to every function, which is why you don't see it listed in the prototype for Box::new
:
fn new(x: T) -> Box<T>
请注意,它按值(或移动)占用x
,因此您甚至需要知道调用该函数的大小.
Notice that it takes x
by value (or move), so you need to know how big it is to even call the function.
相反,Box
类型本身不需要 ;它使用(再次特殊的)特征绑定?Sized
,表示选择退出默认的Sized
绑定":
In contrast, the Box
type itself does not require Sized
; it uses the (again special) trait bound ?Sized
, which means "opt out of the default Sized
bound":
pub struct Box<T> where T: ?Sized(_);
如果您浏览一遍,可以使用一种方法来创建类型不大的Box
:
If you look through, there is one way to create a Box
with an unsized type:
impl<T> Box<T> where T: ?Sized
....
unsafe fn from_raw(raw: *mut T) -> Box<T>
因此从不安全的代码中,您可以从原始指针创建一个.从那时起,所有正常的事情都开始起作用.
so from unsafe code, you can create one from a raw pointer. From then on, all the normal things work.