Rust 铁锈赢了';t让我从匹配中返回一个类型的实例,一直认为我';我试图返回一个值

Rust 铁锈赢了';t让我从匹配中返回一个类型的实例,一直认为我';我试图返回一个值,rust,Rust,根据,我需要执行以下操作以返回特征的实例: trait着色器{} 结构MyShader; MyShader{}的impl着色器 结构图形上下文; impl GraphicsContext{ fn创建_着色器(&self)->impl着色器{ 让shader=MyShader; 着色器 } } 但当我尝试这样做时: pub-trait组件{} 结构种类{} 结构位置{} 类{}的impl组件 位置{}的impl组件 pub fn get(组件名称:&String)->impl组件{ 匹配组件名称

根据,我需要执行以下操作以返回
特征的实例:

trait着色器{}
结构MyShader;
MyShader{}的impl着色器
结构图形上下文;
impl GraphicsContext{
fn创建_着色器(&self)->impl着色器{
让shader=MyShader;
着色器
}
}
但当我尝试这样做时:

pub-trait组件{}
结构种类{}
结构位置{}
类{}的impl组件
位置{}的impl组件
pub fn get(组件名称:&String)->impl组件{
匹配组件名称。作为参考(){
“善良”=>善良,
“位置”=>位置
}
}
我只是得到了一些错误:

错误[E0423]:预期值,找到结构
Kind
-->src/main.rs:17:24

|
17 |“善良”=>善良,
|^^^^^你是说'Kind{/*fields*/}'?
错误[E0423]:预期值,找到结构
位置
-->src/main.rs:18:24

|
18 |“位置”=>位置
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^?

编译器必须知道在编译时在堆栈上保留多少空间。正如链接的答案所提到的,如果具体的返回类型是有条件的,那么在运行时之前无法知道所需的空间量。这就是这个答案所指的:

它确实有一些限制,例如[…]当具体返回类型为 有条件的在这些情况下,您需要使用trait对象答案 下面


如果希望有条件地返回
种类
位置
,则应使用该答案中所示函数的第二种形式。在这种情况下,将在堆上而不是堆栈上创建
种类
位置
;堆栈将包含一个拥有该堆引用的
Box
,而
Box
是一种类型,其大小在编译时是已知的。

编译器必须知道在编译时堆栈上要保留多少空间。正如链接的答案所提到的,如果具体的返回类型是有条件的,那么在运行时之前无法知道所需的空间量。这就是这个答案所指的:

它确实有一些限制,例如[…]当具体返回类型为 有条件的在这些情况下,您需要使用trait对象答案 下面


如果希望有条件地返回
种类
位置
,则应使用该答案中所示函数的第二种形式。在这种情况下,将在堆上而不是堆栈上创建
种类
位置
;堆栈将包含一个拥有堆引用的
Box
,而
Box
是一种编译时已知大小的类型。

作为返回类型的
impl Component
基本上是一个
T,其中T:Component
,其中
T
由函数本身而不是调用方选择

T
可以是
Kind
T
可以是
Location
,但
T
不能同时是两者

两种解决方案:

  • 动态:返回一个
    Box
    并返回
    Box::new(种类{})
    Box::new(位置{})
    。缺点是它会导致堆分配

  • 静态地,通过返回
    枚举

  • enum KindOrLocation{
    种类(种类),,
    地点(地点),,
    }
    
    要使其可用作
    组件
    ,可以实现
    Deref

    impl-Deref用于KindOrLocation{
    目标类型=动态元件+静态;
    fn deref(&self)->&self::Target{
    匹配自我{
    KindOrLocation::Kind(x)=>x,
    KindOrLocation::位置(x)=>x,
    }
    }
    }
    
    这里的缺点是您必须编写这个样板代码


    顺便说一下:

    • 如果使用
      {}
      定义结构,如
      struct Kind{}
      ,则可以通过编写
      Kind{}
      ,而不仅仅是
      Kind
      来创建它的对象
    • 您需要在您的比赛中处理
      \uu
      案例:
      \u=>恐慌!()
      什么的
    • 不要使用
      &String
      ,而是使用
      &str
      。然后它同时适用于
      &String
      &str

    • 作为返回类型的
      impl Component
      基本上是一个
      T,其中T:Component
      ,其中
      T
      由函数本身而不是调用方选择

      T
      可以是
      Kind
      T
      可以是
      Location
      ,但
      T
      不能同时是两者

      两种解决方案:

    • 动态:返回一个
      Box
      并返回
      Box::new(种类{})
      Box::new(位置{})
      。缺点是它会导致堆分配

    • 静态地,通过返回
      枚举

    • enum KindOrLocation{
      种类(种类),,
      地点(地点),,
      }
      
      要使其可用作
      组件
      ,可以实现
      Deref

      impl-Deref用于KindOrLocation{
      目标类型=动态元件+静态;
      fn deref(&self)->&self::Target{
      匹配自我{
      KindOrLocation::Kind(x)=>x,
      KindOrLocation::位置(x)=>x,
      }
      }
      }
      
      这里的缺点是您必须编写这个样板代码


      顺便说一下:

      • 如果使用
        {}
        定义结构,如
        struct Kind{}
        ,则可以通过编写
        Kind{}
        ,而不仅仅是
        Kind
        来创建它的对象
      • 您需要在您的比赛中处理
        \uu
        案例:
        \u=>恐慌!()
        或者别的什么