简体   繁体   English

我可以为单个结构以不同的方式多次实现相同的特征吗?

[英]Can I implement the same trait multiple times in different ways for a single struct?

I'd like to serialize a struct in two different ways depending of the situation but I'm facing a problem: with my current knowledge I can only serialize the struct in one way.我想根据情况以两种不同的方式序列化结构,但我面临一个问题:以我目前的知识,我只能以一种方式序列化结构。

Here is my code with #[derive(Serialize)] (auto derive)这是我的代码#[derive(Serialize)] (自动派生)

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct TransactionContent {
    sender_addr: Vec<u8>,
    sender_pubkey: Vec<u8>,
    receiver_addr: Vec<u8>,
    amount: u32,
    timestamp: i64
}

I'm using bincode::serialize to serialize my struct and make it a Vec<u8> and I also want to store that struct in a JSON file.我使用bincode::serialize连载我的结构,使之成为Vec<u8>想给结构存储在一个JSON文件。 When serializing to JSON, I'd like to serialize it in my own way, like returning a base58 string for the Vec<u8> fields.当序列化为 JSON 时,我想以我自己的方式序列化它,比如为Vec<u8>字段返回一个 base58 字符串。

This is my own implementation:这是我自己的实现:

impl Serialize for TransactionContent {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        let mut state = serializer.serialize_struct("TransactionContent", 5)?;
        state.serialize_field("sender_addr", &self.sender_addr.to_base58())?;
        state.serialize_field("sender_pubkey", &self.sender_pubkey.to_base58())?;
        state.serialize_field("receiver_addr", &self.receiver_addr.to_base58())?;
        state.serialize_field("amount", &self.amount)?;
        state.serialize_field("timestamp", &self.timestamp)?;
        state.end()
    }
}

I can't use the above code simultaneously.我不能同时使用上面的代码。 If I use the auto derive, the second Impl isn't possible.如果我使用自动派生,则第二个Impl是不可能的。 If I use the second one, the bincode::serialize function will work but not as I want it to (I want to use Vec<u8> for it)如果我使用第二个, bincode::serialize函数将起作用,但不是我想要的(我想使用Vec<u8>

Is there a way that I could use both Impl at the same time?有没有办法可以同时使用两个Impl Something like a conditional Impl for example?例如,像条件Impl这样的东西?

No, you cannot implement the same trait multiple times in multiple ways for a single type.不,您不能为单一类型以多种方式多次实现相同的特征。

As mentioned in a comment , you can create a newtype that wraps the full data and implement the required traits on that:作为在评论中提到,你可以创建一个包装完整的数据NEWTYPE和实施所要求的特质:

use serde::{ser::SerializeStruct, Serialize, Serializer}; // 1.0.117
use serde_json; // 1.0.59

#[derive(Debug, Serialize)]
struct Real {
    data: Vec<u8>,
}

struct AsJson<'a>(&'a Real);

impl<'a> Serialize for AsJson<'a> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut state = serializer.serialize_struct("Thing", 1)?;
        state.serialize_field("data", b"this is some data")?;
        state.end()
    }
}

fn main() {
    let r = Real {
        data: vec![1, 2, 3, 4],
    };
    println!("{:?}", serde_json::to_string(&r));
    println!("{:?}", serde_json::to_string(&AsJson(&r)));
}

If you control the trait如果你控制了特质

You could add a generic parameter to the trait and implement it multiple times for the same type:您可以向特征添加一个泛型参数并为同一类型多次实现它:

trait Example<T> {}

struct Style1;
struct Style2;

impl Example<Style1> for i32 {}
impl Example<Style2> for i32 {}

This isn't without downsides though.但这并非没有缺点。

See also:另见:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在单个单元测试中多次模拟 httpclient - Mocking httpclient multiple times in a single Unit Test 在运行时多次编译同一个.dll - Compile multiple times the same .dll in runtime 两个不同的程序可以对同一个文件执行I / O同步吗? - Can two different program perform synchronization on the same file for I/O? Django Rest 框架正在使用相同的序列化器以两种不同的方式序列化 object - Django Rest Framework is serializing an object two different ways using the same serializer 如何在Ember中表示具有多个不同序列化的模型? - How can I represent a model with multiple different serializations in Ember? 序列化Java中的多个不同对象 - Serialize multiple different objects single in Java 如何在不同的 API 中为同一字段使用不同的名称?—Jackson - How can I have different names for the same field in different APIs?—Jackson 我有一个单一文件,需要随机序列化多个对象。我怎么能在c#中? - I have a Single File And need to serialize multiple objects randomly. How can I in c#? 反序列化SDMPackageXML的两种不同方法 - Two different ways to deserialize SDMPackageXML 如何使用2个不同类型的相同xml元素和属性名称反序列化xml? - How can I deserialize xml with 2 different types of the same xml element and property name?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM