< T:Trait>有什么区别? Box T和& Trait/Box< Trait&gt ;? [英] What is the difference between <T: Trait> Box<T> and &Trait / Box<Trait>?

查看:102
本文介绍了< T:Trait>有什么区别? Box T和& Trait/Box< Trait&gt ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编写具有特征的代码时,可以将特征置于特征绑定中:

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.

这篇关于&lt; T:Trait&gt;有什么区别? Box T和&amp; Trait/Box&lt; Trait&gt ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆