提问人:ZJaume 提问时间:7/18/2023 更新时间:7/19/2023 访问量:69
并行 json 反序列化失败,并显示有效的 json
Parallel json deserialization fails with valid json
问:
我想使用 并行反序列化 json 值。当尝试在内部反序列化时,示例中的有效 json 失败,尽管在没有并行化的情况下被正确解析。代码如下:rayon
serde-json
par_iter
use rayon::prelude::*; // 1.7.0
use serde_json::{Result, Value};
fn main() -> Result<()> {
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
let v: Value = serde_json::from_str(data)?;
println!("Please call {} at the number {}", v["name"], v["phones"][0]);
let mut batch = Vec::<String>::new();
batch.push(data.to_string());
batch.push(data.to_string());
let _values = batch.par_iter()
.for_each(|json: &String| {
serde_json::from_str(json.as_str()).unwrap()
});
Ok(())
}
这就是错误
thread 'thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: map, expected unit", line: 2, column: 8)', src/main.rs:23:49
IIRC,我见过其他使用内部的例子。这不推荐吗?就我而言,我想这样做,因为如果输入无效,我需要程序崩溃。par_iter
unwrap
答:
1赞
Finomnis
7/19/2023
#1
serde_json::from_str
根据写入的变量类型自动确定其输出类型。但是,在您的例子中,不需要返回值,因此请尝试将其反序列化为 .for_each
from_str
()
与注释一起使用以使其工作:map().collect()
: Vec<Value>
use rayon::prelude::*; // 1.7.0
use serde_json::{Result, Value};
fn main() -> Result<()> {
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
let v: Value = serde_json::from_str(data)?;
println!("Please call {} at the number {}", v["name"], v["phones"][0]);
let mut batch = Vec::<String>::new();
batch.push(data.to_string());
batch.push(data.to_string());
let values: Vec<Value> = batch
.par_iter()
.map(|json: &String| serde_json::from_str(json.as_str()).unwrap())
.collect();
println!("Values:\n{:#?}", values);
Ok(())
}
Please call "John Doe" at the number "+44 1234567"
Values:
[
Object {
"age": Number(43),
"name": String("John Doe"),
"phones": Array [
String("+44 1234567"),
String("+44 2345678"),
],
},
Object {
"age": Number(43),
"name": String("John Doe"),
"phones": Array [
String("+44 1234567"),
String("+44 2345678"),
],
},
]
虽然老实说,使用起来有点奇怪;通常人们直接反序列化为结构:serde::Value
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Debug, Serialize, Deserialize)]
struct Entry {
name: String,
age: u32,
phones: Vec<String>,
}
fn main() -> Result<()> {
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
let v: Entry = serde_json::from_str(data)?;
println!("Please call {} at the number {}", v.name, v.phones[0]);
let mut batch = Vec::<String>::new();
batch.push(data.to_string());
batch.push(data.to_string());
let values: Vec<Entry> = batch
.par_iter()
.map(|json: &String| serde_json::from_str(json.as_str()).unwrap())
.collect();
println!("Values:\n{:#?}", values);
Ok(())
}
Please call John Doe at the number +44 1234567
Values:
[
Entry {
name: "John Doe",
age: 43,
phones: [
"+44 1234567",
"+44 2345678",
],
},
Entry {
name: "John Doe",
age: 43,
phones: [
"+44 1234567",
"+44 2345678",
],
},
]
评论
.for_each
_values
()
serde_json::from_str
let v: Value = serde_json::from_str(json.as_str()).unwrap();
try_for_each()存在
)。par_iter()