How to convert a boxed trait into a trait reference?

徘徊边缘 提交于 2021-01-19 03:57:53

问题


I have the following code that tries to take a reference to a trait object from a boxed trait:

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;
}

The compiler returns the following error:

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`

How do I properly borrow &T from Box<T>?


回答1:


Box<T> implements the AsRef<T> trait, which provides the method as_ref(), so you can turn it into a reference that way:

let trait_ref: &T = trait_box.as_ref();

Normally, deref coercions mean that you don't usually need to write this out explicitly. If you pass a value of type Box<T> to a function that takes &T, the compiler will insert the conversion for you. If you want to call one of the methods on T that takes &self, the compiler will insert the conversion for you. However, deref coercions don't apply to traits, so this won't happen for trait objects.




回答2:


Borrow the contents of the Box, rather than the Box itself:

let trait_ref: &T = &*trait_box;

The reason the line involving &S works is because the only way for Rust to get from Box<S> to &S is via "deref coercion"; that is, it repeatedly dereferences the value until either the types match, or it can't dereference any further.

Coercing to a trait object, on the other hand, isn't done using dereferencing at all; it involves constructing a new pointer directly from the given one. If it can't do that, it fails.



来源:https://stackoverflow.com/questions/49218474/how-to-convert-a-boxed-trait-into-a-trait-reference

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!