代码之家  ›  专栏  ›  技术社区  ›  Isaksak

从函数返回泛型类型时出现问题

  •  0
  • Isaksak  · 技术社区  · 2 年前

    我有一个函数,它搜索特征对象的列表,并试图找到一个实现者是特定类型的对象,但是编译器不接受返回类型。

    pub struct GameObject{
        pub modules: Vec<Box<dyn ModuleTrait>>, 
    }
    
    impl GameObject {
       pub fn find_module_of_type<T: ModuleTrait>(&self) -> Result<T> {  
            //iterate through the modules
            self.modules
                .iter()
                .for_each(|m| {
                    let module = m.as_any().downcast_ref::<T>();
    
                    //see if mosule is of the correct type 
                    if match module {
                        Some(T) => true,
                        None => false,
                    } {
                        return Ok(module); //this is where the error happens
                    }
                });
                
            Err(anyhow!("The specified module could not be found"))
        }
    }
    
    pub trait ModuleTrait {
        fn as_any(&self) -> &dyn Any;
    }
    
    pub struct Transform{
        pub value: i32
    }
    
    impl ModuleTrait for Transform {
        fn as_any(&self) -> &dyn Any {
            self
        }
    }
    

    这给出了错误

    error[E0308]: mismatched types
      --> src\scene\game_object.rs:42:28
       |
    42 |                     return Ok(module);
       |                            ^^^^^^^^^^ expected `()`, found `Result<Option<&T>, _>`
       |
       = note: expected unit type `()`
                       found enum `std::result::Result<Option<&T>, _>`
    note: return type inferred to be `()` here
      --> src\scene\game_object.rs:42:28
       |
    42 |                     return Ok(module);
       |                            ^^^^^^^^^^
    
    For more information about this error, try `rustc --explain E0308`
    

    错误消息让我更加困惑,因为它首先告诉我单元返回类型是推断的,但同时它不是单元类型。

    我试图打开模块,但给出的错误信息大致相同

    1 回复  |  直到 2 年前
        1
  •  3
  •   cafce25    2 年前

    Finding an object already has a method on Iterator 既然你想和我一样改变类型 find_map 此处改为:

    impl GameObject {
        pub fn find_module_of_type<T: ModuleTrait + 'static>(&self) -> Option<&T> {
            self.modules
                .iter()
                .find_map(|m| m.as_any().downcast_ref::<T>())  
        }
    }
    

    所做的修改:

    • for_each find_map 那毕竟是你想做的。
    • Result Option 如果你唯一的错误是“找不到对象匹配标准”,那就是 选项 是的。如果你想在呼叫链上进一步消除错误的歧义,你可以随时打开它 选项 变成 后果 具有 Option::ok_or 那里
    • 既然你只得到一个推荐人,却不知道如何 Copy Clone T 你不能真正返回一个值,只能返回一个引用,所以 Option<T> Option<&T>
    • 添加了的绑定 T: 'static 因为这是能够 downcast 看上面的 Any )。
    推荐文章