我有一个使用match来确定要调用哪个Serde反序列化函数的特征(我在这里放了Self::default作为占位符).特征定义中的实现对于实现特征的所有 struct ("yaml""json")所支持的格式具有匹配臂.还有一些 struct 也支持"csv",所以我为这些 struct 制作了一个专门的方法,并重写了match.

有没有一种方法可以不重写相同的方法,只添加一个匹配手臂?在我的实际代码中,这个函数做其他的事情,所以复制、粘贴和添加一个匹配手臂是很烦人的.

下面是一个例子:

pub trait MyTrait: Default {
    fn from_file(format: &str) -> Self {
        match format {
            "yaml" => Self::default(),
            "json" => Self::default(),
            _ => panic!(),
        }
    }
}

#[derive(Debug, Default)]
struct MyStruct {a: i32, b: i32}

impl MyTrait for MyStruct {
    fn from_file(format: &str) -> Self {
        match format {
            "yaml" => Self::default(),
            "json" => Self::default(),
            "csv" => Self { a: 1, b: 1 },
            _ => panic!(),
        }
    }
}

fn main() {
    let example1 = MyStruct::from_file("yaml");
    dbg!(example1);
    
    let example2 = MyStruct::from_file("csv");
    dbg!(example2);
}

Rust playground

推荐答案

您可以创建另一个函数并将其用作后备,而不是直接panic .然后仅在实现特征时覆盖该函数.

pub trait MyTrait: Default {
    fn from_file(format: &str) -> Self {
        match format {
            "yaml" => Self::default(),
            "json" => Self::default(),
            _ => Self::from_other_file(format),
        }
    }

    fn from_other_file(format: &str) -> Self {
        panic!("unable to deserialize from {format:?}");
    }
}

impl MyTrait for MyStruct {
    fn from_other_file(format: &str) -> Self {
        match format {
            "csv" => Self { a: 1, b: 1 },
            _ => panic!(),
        }
    }
}

Rust相关问答推荐

Rust kill std::processs::child

在本例中,为什么我不能一次多次borrow 可变变量?

创建Rust中元对象协议的动态对象 Select /重新分配机制

Trait bound i8:来自u8的不满意

`*mut[T]`与`*mut T`的区别

在Rust中声明和定义一个 struct 体有什么区别

如何将 struct 数组放置在另一个 struct 的末尾而不进行内存分段

为什么我们有两种方法来包含 serde_derive?

Google chrome 和 Apple M1 中的计算着色器

Rust:为什么 Pin 必须持有指针?

Rust中如何实现一个与Sized相反的负特性(Unsized)

我如何取消转义,在 Rust 中多次转义的字符串?

在 Rust 中使用 `SecTrustSettingsSetTrustSettings` 绑定导致 `errSecInternalComponent`

了解 Rust 闭包:为什么它们持续持有可变引用?

Rust 异步和 AsRef 未被发送

如何获取包裹在 Arc<> 和 RwLock<> 中的 Rust HashMap<> 的长度?

为什么这个值在上次使用后没有下降?

Rust 内联 asm 中的向量寄存器:不能将 `Simd` 类型的值用于内联汇编

如何将 while 循环内的用户输入添加到 Rust 中的向量?

函数参数的 Rust 功能标志