< T:Trait>有什么区别? Box T和& Trait/Box< Trait> ;? [英] What is the difference between <T: Trait> Box<T> and &Trait / Box<Trait>?
问题描述
编写具有特征的代码时,可以将特征置于特征绑定中:
When writing code with traits you can put the trait in a trait bound:
use std::fmt::Debug;
fn myfunction1<T: Debug>(v: Box<T>) {
println!("{:?}", v);
}
fn myfunction2<T: Debug>(v: &T) {
println!("{:?}", v);
}
fn main() {
myfunction1(Box::new(5));
myfunction2(&5);
}
或直接以Box
或引用类型:
use std::fmt::Debug;
fn myfunction3(v: Box<Debug>) {
println!("{:?}", v);
}
fn myfunction4(v: &Debug) {
println!("{:?}", v);
}
fn main() {
myfunction3(Box::new(5));
myfunction4(&5);
}
这些给出相同的输出.那有什么区别?
These give the same output. So what is the difference?
(This question was inspired by another question where this was just one of several intermingled concepts)
推荐答案
对于<T: Trait> Box<T>
,您正在使用特质绑定来告诉编译器,您想要的Box
具有类型为T
的实例,该实例实现了Trait
,并且在使用时将指定T
. Rust编译器可能会为您代码中的每个不同T
创建不同,高效的代码(同质化).
With <T: Trait> Box<T>
you are using a trait bound to tell the compiler that you want a Box
with an instance of some type T
which implements Trait
, and you will specify T
when you use it. The Rust compiler will likely create different, efficient, code for each different T
in your code (monomorphization).
使用Box<Trait>
告诉编译器您想要具有特征对象的Box
,该指针指向实现Trait
的 unknown 类型的指针,这意味着编译器将使用动态调度.
With Box<Trait>
you are telling the compiler that you want a Box
with a trait object, a pointer to an unknown type which implements Trait
, which means that the compiler will use dynamic dispatch.
我提供了两个示例,使两者之间的区别更加明显:
I've included two examples which makes the difference a bit clearer:
<T: Trait> Box<T>
,即特征绑定:
use std::fmt::Debug;
struct Wrapper<T> {
contents: Option<Box<T>>,
}
impl<T: Debug> Wrapper<T> {
fn new() -> Wrapper<T> {
Wrapper { contents: None }
}
fn insert(&mut self, val: Box<T>) {
}
}
fn main() {
let mut w = Wrapper::new();
// makes T for w be an integer type, e.g. Box<i64>
w.insert(Box::new(5));
// type error, &str is not an integer type
// w.insert(Box::new("hello"));
}
Box<Trait>
,即特征对象:
use std::fmt::Debug;
struct Wrapper {
contents: Option<Box<Debug>>,
}
impl Wrapper {
fn new() -> Wrapper {
Wrapper { contents: None }
}
fn insert(&mut self, val: Box<Debug>) {
}
}
fn main() {
let mut w = Wrapper::new();
w.insert(Box::new(5));
w.insert(Box::new("hello"));
}
For further details on the difference between trait bounds and trait objects I recommend the section on trait objects in the first edition of the Rust book.
这篇关于< T:Trait>有什么区别? Box T和& Trait/Box< Trait> ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!