-2

我想要的结果如下,但Rust的结果是另一个。

 [123 34 66 111 100 121 34 58 34 97 71 86 115 98 71 56 61 34 125]

golang 示例:

type Response struct {
    Body    []byte
}
func Test_Marshal(t *testing.T)  {
    body := "hello"
    resp := &Response{
        Body:[]byte(body),
    }
    t.Log("resp:", resp)
    result, _ := json.Marshal(resp)
    t.Log("result: ", result)
}

去结果:

    aa_test.go:17: resp: &{[104 101 108 108 111]}
    aa_test.go:19: result:  [123 34 66 111 100 121 34 58 34 97 71 86 115 98 71 56 61 34 125]

生锈样品:

use serde_json::{Result, Value};
use serde::Serialize;

#[derive(Serialize, Debug)]
pub struct Response {
    pub body: ::std::vec::Vec<u8>,
}

fn main() {
    let body_str = "hello".to_string();
    let resp = Response {
        body: Vec::from(body_str)
    };

    println!("resp: {:?}", resp);

    let result = serde_json::to_vec(&resp).unwrap();
    println!("result: {:?}",result)
}

生锈结果

resp: Response { body: [104, 101, 108, 108, 111] }
result: [123, 34, 98, 111, 100, 121, 34, 58, 91, 49, 48, 52, 44, 49, 48, 49, 44, 49, 48, 56, 44, 49, 48, 56, 44, 49, 49, 49, 93, 125]

4

1 回答 1

5

如果我们将您的两个输出都从字节数组转换为 ASCII 字符串(我使用了一个简单的 Javascript 代码 - array.map(ch => String.fromCharCode(ch)).join("")),我们将得到以下结果:

// for Rust
{"body":[104,101,108,108,111]}
// for Go
{"Body":"aGVsbG8="}

因此,似乎有两个区别:

  • 第一个也是最明显的是字段命名。两个序列化器都将 JSON 中的字段名称保留在源代码中,因此在 Go 中是Body(大写),而在 Rust 中是body(小写)。
  • 第二个是Rust按原样编码值 - 即字节数组被视为数字向量(它没有得到任何特殊处理)。然而,在 Go 中,它被转换为 Base64 字符串——这是一个明确记录的异常,可能是因为在大多数情况下这是预期的行为。

现在,在这里做什么?这取决于您要使用的行为。我不知道如何用 Go 改变输出,所以我认为它是正确的,Rust 需要调整。

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
pub struct Response {
    #[serde(with="base64")]
    pub body: Vec<u8>,
}

mod base64 {
    use serde::{Serialize, Deserialize};
    use serde::{Deserializer, Serializer};

    pub fn serialize<S: Serializer>(v: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
        let base64 = base64::encode(v);
        String::serialize(&base64, s)
    }
    
    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
        let base64 = String::deserialize(d)?;
        base64::decode(base64.as_bytes())
            .map_err(|e| serde::de::Error::custom(e))
    }
}
于 2021-12-27T06:47:10.687 回答