Rust 在框中指定通用实现以使用匹配项

Rust 在框中指定通用实现以使用匹配项,rust,Rust,我想写一个函数,返回实现一个公共特性的结构 如果我的函数指定了返回类型->impl MyTrait,则在使用匹配项时,我将无法兼容,因为匹配项必须返回相同的类型。例如: fn获取结构(枚举:MyEnum)->impl MyTrait{ 匹配一个枚举{ MyEnum::MyEnumFoo=>MyStruct1{}, MyEnum::MyEnumBar=>MyStruct2{}, } } 产生: 错误[E0308]:匹配臂的类型不兼容 -->src/main.rs:22:5 | 22 |/匹配一个

我想写一个函数,返回实现一个公共特性的结构

如果我的函数指定了返回类型
->impl MyTrait
,则在使用匹配项时,我将无法兼容,因为匹配项必须返回相同的类型。例如:

fn获取结构(枚举:MyEnum)->impl MyTrait{
匹配一个枚举{
MyEnum::MyEnumFoo=>MyStruct1{},
MyEnum::MyEnumBar=>MyStruct2{},
}
}
产生:

错误[E0308]:匹配臂的类型不兼容
-->src/main.rs:22:5
|
22 |/匹配一个|枚举{
23 | | MyEnum::MyEnumFoo=>MyStruct1{},
24 | | MyEnum::MyEnumBar=>MyStruct2{},
||-----------将arm与不兼容的类型匹配
25 | |     }
|| uuuu^应为结构'MyStruct1',找到结构'MyStruct2'`
|
=注意:应为'MyStruct1'类型`
找到类型`MyStruct2`
如果我用
进行尝试,如下所示:

trait-MyTrait{
fn my_func(){}
}
髓鞘{
MyEnumFoo,
我的,
}
结构MyStruct1{}
结构MyStruct2{}
为MyStruct1导入MyTrait{
fn my_func(){
println!(“来自MyStruct1的你好世界”)
}
}
为MyStruct2导入MyTrait{
fn my_func(){
println!(“来自MyStruct2的你好世界”)
}
}
fn获取结构(枚举:MyEnum)->Box{
匹配一个枚举{
MyEnum::MyEnumFoo=>Box::new(MyStruct1{}),
MyEnum::MyEnumBar=>Box::new(MyStruct2{}),
}
}
error[E0038]:无法将特征'MyTrait'生成对象
-->src/main.rs:21:1
|
21 | fn获取结构(枚举:MyEnum)->框{
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
=注意:方法'my_func'没有接收器
在这种情况下,我不知道如何使用特质

如何编写一个返回实现相同特征的结构的函数

可以在中找到部分响应,但没有一个答案解决对象安全问题


OOP中的类似行为可以通过接口指定返回类型。

正如编译器消息所说,您需要向
my\u func
方法添加一个接收器:
fn my\u func()
->
fn my\u func(&self)

之所以有必要这样做,是因为它需要是对象安全的

您的案例的具体要求如下:

必须有一个具有类型
Self
或对
Self
类型

现在,这意味着
self
&self
&mut self
self:Box
,但最终应该扩展到自定义类型,如
self:Rc

使用std::fmt::Debug;
fn main(){
println!(“Foo=>{:?}”,获取一个结构(MyEnum::MyEnumFoo));
println!(“Bar=>{:?}”,获取一个结构(MyEnum::MyEnumBar));
}
特性MyTrait:调试{
fn my_func(&self){}
}
髓鞘{
MyEnumFoo,
我的,
}
#[导出(调试)]
结构MyStruct1{}
#[导出(调试)]
结构MyStruct2{}
为MyStruct1导入MyTrait{
fn my_func(&self){
println!(“来自MyStruct1的你好世界”)
}
}
为MyStruct2导入MyTrait{
fn my_func(&self){
println!(“来自MyStruct2的你好世界”)
}
}
fn获取结构(枚举:MyEnum)->Box{
匹配一个枚举{
MyEnum::MyEnumFoo=>Box::new(MyStruct1{}),
MyEnum::MyEnumBar=>Box::new(MyStruct2{}),
}
}

您的答案与建议的重复答案有何不同?我在开始编写时没有看到该链接;我还将从RFC0255中提供更多详细信息。第一个重复链接仅解决问题的第一部分,第二个重复链接讨论另一个问题。因此,该问题不是重复的。同样,没有一个重复的问题NSWER解决了对象安全问题。是的,这是两者的结合。第一个dup解决了
impl Trait
作为返回类型的一般问题,第二个dup解决了“Trait
MyTrait
不能成为对象”的问题。
use std::fmt::Debug;

fn main() {
    println!("Foo => {:?}", get_a_struct(MyEnum::MyEnumFoo));
    println!("Bar => {:?}", get_a_struct(MyEnum::MyEnumBar));
}

trait MyTrait :Debug{
    fn my_func(&self) {}
}

enum MyEnum {
    MyEnumFoo,
    MyEnumBar,
}

#[derive(Debug)]
struct MyStruct1 {}

#[derive(Debug)]
struct MyStruct2 {}

impl MyTrait for MyStruct1 {
    fn my_func(&self) {
        println!("Hello world from MyStruct1")
    }
}

impl MyTrait for MyStruct2 {
    fn my_func(&self) {
        println!("Hello world from MyStruct2")
    }
}

fn get_a_struct(an_enum: MyEnum) -> Box<dyn MyTrait> {
    match an_enum {
        MyEnum::MyEnumFoo => Box::new(MyStruct1 {}),
        MyEnum::MyEnumBar => Box::new(MyStruct2 {}),
    }
}