简体   繁体   English

返回对 Box 的引用<dyn trait></dyn>

[英]Returning a reference to a Box<dyn Trait>

Started learning rust this weekend, and I'm trying to write a little private helper method on my class to look up some internal values, but it's proving quite complicated.这个周末开始学习 rust,我试图在我的 class 上写一个小的私有辅助方法来查找一些内部值,但事实证明它相当复杂。 I have a few structs implementing a trait:我有一些实现特征的结构:

trait Animal {}

struct Dog {}
impl Dog for Animal{}

struct Cat{}
impl Cat for Animal{}

along with a container which holds multiple variants of animal:以及一个装有多种动物变体的容器:

struct Person {
  my_dog: Dog,
  my_cat: Cat
}

What I want to do is write a helper which looks up the appropriate Animal, like this:我想要做的是编写一个帮助程序来查找合适的动物,如下所示:

impl Person {
  fn look_up_animal(&self, animal_name: &str) -> Box<&dyn Animal> {
    match animal_name {
      "dog" => Box::from(&self.my_dog),
      "cat" => Box::from(&self.my_cat)
    }
  }
}

Unfortunately, I can't quite figure out how to do the types for this.不幸的是,我不太清楚如何为此做类型。 The version above using references and Box gives an error like "expected struct Box<&dyn Animal> but got struct Box<&Dog> , so I'm not really sure how to convert a regular value into a dyn value.上面使用引用Box的版本给出了类似“expected struct Box<&dyn Animal> but got struct Box<&Dog>的错误,所以我不太确定如何将常规值转换为dyn值。

The fully explicit version of what you want would be你想要的完全明确的版本是

impl Person {
    fn look_up_animal(&self, animal_name: &str) -> Option<Box<&dyn Animal>> {
        match animal_name {
            "dog" => Some(Box::from(&self.my_dog as &dyn Animal)),
            "cat" => Some(Box::from(&self.my_cat as &dyn Animal)),
            _ => None,
        }
    }
}

Rust is able to coerce one layer of references to trait objects, but two layers of references (both Box and & ) trips it up. Rust 能够强制对特征对象的一层引用,但是两层引用( Box& )将其绊倒。 (Having a reference inside a Box also triggers a clippy warning.) That suggests another solution. (在Box中有一个引用也会触发一个clippy警告。)这提出了另一种解决方案。

impl Person {
    fn look_up_animal(&self, animal_name: &str) -> Option<&dyn Animal> {
        match animal_name {
            "dog" => Some(&self.my_dog as &dyn Animal),
            "cat" => Some(&self.my_cat as &dyn Animal),
            _ => None,
        }
    }
}

This time, the explicit cast as &dyn Animal is unnecessary since there's just a single layer of references.这一次,显式转换as &dyn Animal是不必要的,因为只有一层引用。

impl Person {
    fn look_up_animal(&self, animal_name: &str) -> Option<&dyn Animal> {
        match animal_name {
            "dog" => Some(&self.my_dog),
            "cat" => Some(&self.my_cat),
            _ => None,
        }
    }
}

(playground link) (游乐场链接)


Note: I added in the Option so that there's something to return when animal_name isn't "dog" or "cat" .注意:我在Option中添加了一些东西,以便在animal_name不是"dog""cat"时返回一些东西。 You could also panic or default to something else that implements Animal .您也可能会恐慌或默认使用其他实现Animal的东西。

Started learning rust this weekend, and I'm trying to write a little private helper method on my class to look up some internal values, but it's proving quite complicated.这个周末开始学习 rust,我正在尝试在我的 class 上编写一个小的私有帮助方法来查找一些内部值,但事实证明它相当复杂。 I have a few structs implementing a trait:我有一些实现特征的结构:

trait Animal {}

struct Dog {}
impl Dog for Animal{}

struct Cat{}
impl Cat for Animal{}

along with a container which holds multiple variants of animal:以及一个装有多种动物变体的容器:

struct Person {
  my_dog: Dog,
  my_cat: Cat
}

What I want to do is write a helper which looks up the appropriate Animal, like this:我想要做的是编写一个查找适当动物的助手,如下所示:

impl Person {
  fn look_up_animal(&self, animal_name: &str) -> Box<&dyn Animal> {
    match animal_name {
      "dog" => Box::from(&self.my_dog),
      "cat" => Box::from(&self.my_cat)
    }
  }
}

Unfortunately, I can't quite figure out how to do the types for this.不幸的是,我不太清楚如何为此做类型。 The version above using references and Box gives an error like "expected struct Box<&dyn Animal> but got struct Box<&Dog> , so I'm not really sure how to convert a regular value into a dyn value.上面使用引用Box的版本给出了一个错误,如 "expected struct Box<&dyn Animal> but got struct Box<&Dog> ,所以我不确定如何将常规值转换为dyn值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM