[英]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)));
}
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.