Rust 不允许我从匹配中返回一个类型的实例,一直认为我正在尝试返回一个值

标签 rust

根据 this answerthis questions我需要执行以下操作以返回 Trait 的实例:

trait Shader {}

struct MyShader;
impl Shader for MyShader {}

struct GraphicsContext;

impl GraphicsContext {
    fn create_shader(&self) -> impl Shader {
        let shader = MyShader;
        shader
    }
}

但是当我尝试这样做时:

pub trait Component { }

struct Kind {}

struct Location {}

impl Component for Kind {}

impl Component for Location {}

pub fn get(comp_name: &String) -> impl Component {
    match comp_name.as_ref() {
        "kind"      => Kind,
        "location"  => Location
    }
}

我只是得到错误:

error[E0423]: expected value, found struct Kind --> src/main.rs:17:24

   |
17 |         "kind"      => Kind,
   |                        ^^^^ did you mean `Kind { /* fields */ }`?

error[E0423]: expected value, found struct Location --> src/main.rs:18:24

   |
18 |         "location"  => Location
   |                        ^^^^^^^^ did you mean `Location { /* fields */ >}`?

最佳答案

那个impl Component因为返回类型基本上是 T where T: Component , 其中T由函数本身而不是调用者选择。

T可以是Kind , T可以是Location ,但是 T不能同时兼顾。

两种解决方案:

  1. 动态地:返回 Box<dyn Component>并返回 Box::new(Kind{})Box::new(Location{}) .缺点是它会导致堆分配。

  2. 静态地,通过返回 enum :

enum KindOrLocation {
    Kind(Kind),
    Location(Location),
}

使它可以用作 Component , 你可以实现 Deref<Target = dyn Component> :

impl Deref for KindOrLocation {
    type Target = dyn Component + 'static;
    fn deref(&self) -> &Self::Target {
        match self {
            KindOrLocation::Kind(x) => x,
            KindOrLocation::Location(x) => x,
        }
    }
}

这里的缺点是您必须编写此样板代码。


顺便说一句:

  • 如果你用 {} 定义结构喜欢struct Kind {} ,您通过编写 Kind{} 创建它的一个对象,不只是 Kind .
  • 您需要处理 _你的比赛中的案例:_ => panic!()什么的。
  • 不要拿&String , 但取 &str反而。然后它适用于两者 &String&str .

关于Rust 不允许我从匹配中返回一个类型的实例,一直认为我正在尝试返回一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55540512/

相关文章:

rust - Rocket 无法编译

rust - 返回自定义结果时如何解析 "expected (), found Result"?

memory - 如何检查已编译类型的表示?

macros - Rust 宏可以创建编译时字符串吗?

regex - 是否有其他正则表达式语法可避免出现 “look-around, including look-ahead and look-behind, is not supported”错误?

rust - 为什么函数调用中的尾随逗号不是语法错误?

postgresql - 如何使用 rust-postgres 检查列是否为 NULL?

rust - 我如何知道默认情况下包含哪些 Rust 标准库模块?

rust - 如何使JAWS屏幕阅读器确认动态内容更新

rust - Rust配置 crate 和多态类型