如何将盒装特征转换为特征参考?

Ole*_*sky 3 rust

我有以下代码尝试从盒装特征中引用特征对象:

trait T {}

struct S {}

impl T for S {}

fn main() {
    let struct_box: Box<S> = Box::new(S {});
    let struct_ref: &S = &struct_box;

    let trait_box: Box<T> = Box::new(S {});
    let trait_ref: &T = &trait_box;
}
Run Code Online (Sandbox Code Playgroud)

编译器返回以下错误:

error[E0277]: the trait bound `std::boxed::Box<T>: T` is not satisfied
  --> src/main.rs:12:25
   |
12 |     let trait_ref: &T = &trait_box;
   |                         ^^^^^^^^^^ the trait `T` is not implemented for `std::boxed::Box<T>`
   |
   = note: required for the cast to the object type `T`
Run Code Online (Sandbox Code Playgroud)

如何正确借&TBox<T>

Dan*_*lme 9

Box<T>实现AsRef<T>提供方法trait,as_ref()因此您可以将其转换为引用方式:

let trait_ref: &T = trait_box.as_ref();
Run Code Online (Sandbox Code Playgroud)

通常,deref强制意味着您通常不需要明确地写出来.如果将type的值传递Box<T>给函数,&T编译器将为您插入转换.如果你想调用的一个方法,T这需要&self,编译器会插入你的转换.但是,deref强制不适用于特征,因此特征对象不会发生这种情况.


DK.*_*DK. 6

借用 的内容Box,而不是借用Box本身:

let trait_ref: &T = &*trait_box;
Run Code Online (Sandbox Code Playgroud)

这条线涉及到&S作品的原因是因为 Rust 从Box<S>to的唯一方法&S是通过“deref coercion”;也就是说,它反复取消引用该值,直到类型匹配,或者不能再取消引用。

另一方面,强制使用 trait 对象根本不是使用解引用来完成的;它涉及直接从给定的指针构造一个新的指针。如果它不能做到这一点,它就会失败。