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解决了“TraitMyTrait
不能成为对象”的问题。
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 {}),
}
}