在反序列化时是否有更简单的方法来转换类型?

时间:2017-06-29 23:12:02

标签: rust serde serde-json

使用serde_json,我有String的JSON对象,我需要转换为浮点数。我偶然发现了一个自定义解串器解决方案,但它似乎是一个黑客攻击。 Here is a working playground example of the code below.

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;

use serde_json::Error;
use serde::de::{Deserialize, DeserializeOwned, Deserializer};

#[derive(Serialize, Deserialize)]
struct Example {
    #[serde(deserialize_with = "coercible")]
    first: f64,
    second: f64,
}

fn coercible<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
    T: DeserializeOwned,
    D: Deserializer<'de>,
{
    use serde::de::Error;
    let j = String::deserialize(deserializer)?;
    serde_json::from_str(&j).map_err(Error::custom)
}

fn typed_example() -> Result<(), Error> {
    let data = r#"["3.141",1.618]"#;
    let e: Example = serde_json::from_str(data)?;
    println!("{} {}", e.first * 2.0, e.second * 2.0);
    Ok(())
}

fn main() {
    typed_example().unwrap();
}

上面的代码按照您的预期编译并运行,输出两个浮点数。

我试图了解解串器解决方案的工作原理,但我想知道我是否朝着正确的方向前进,或者是否有更好的方法来实现这一目标。

1 个答案:

答案 0 :(得分:7)

使用 <?php $trNum=$_REQUEST["tr_num"]; include ("dbConnect.php"); @mysql_query("create table 'schedule_".$trNum."'(sid int primary key auto_increment,st_name varchar(20), arr_time varchar(5), dep_time varchar(5), halt varchar(5), dist int, day int);"); echo "Schedule created successfully"; ?> 意外地工作了。有了它,输入coercible被剥夺了"3.141" s,所以我""被送入3.141,它适当地返回了一个浮点数。例如,当输入JSON包含意外值时,这种偶然的解决方案容易且容易混淆。

我阅读了Serde文档(一个很棒的学习练习),并提出了在JSON(working playground here)反序列化时将字符串转换为serde_json::from_str(&j)的适当方法:

f64

感谢Serde开发者,因为尽管Serde documentation似乎对我的眼睛完全是钝的,但事实证明它非常有用且易于理解。我只需要从顶部开始慢慢阅读。