我可能会使用Value::pointer
. 一个例子:
use serde_json::json;
fn main() {
let value = json!({
"deeply": {
"nested": {
"array": [0, 1, 2, 3, 4, 5]
}
}
});
let numbers: Vec<u64> = value
.pointer("/deeply/nested/array")
.unwrap()
.as_array()
.unwrap()
.iter()
.map(|x| x.as_u64().unwrap())
.collect();
println!("{:?}", numbers);
}
注意:此示例包含过度使用unwrap()
调用,这很危险并且可能导致恐慌。它可以使整个示例更简单。
在这种情况下,您不是还在构造多个向量吗?
不,让我们扩展整个机器。
use serde_json::{json, Value};
use std::iter::Map;
use std::slice::Iter;
fn main() {
let value: Value = json!({
"deeply": {
"nested": {
"array": [0, 1, 2, 3, 4, 5]
}
}
});
// Option<&Value> - Option & reference
//
// pub enum Option<T> {
// None,
// Some(T),
// }
//
// T = &Value - reference
let maybe_value_ref: Option<&Value> = value.pointer("/deeply/nested/array");
// &Value - reference
let value_ref: &Value = maybe_value_ref.unwrap();
// Option<&Vec<Value>> - Option & reference
//
// pub enum Option<T> {
// None,
// Some(T),
// }
//
// T = &Vec<Value> - reference to Vec
let maybe_vec_ref: Option<&Vec<Value>> = value_ref.as_array();
// &Vec<Value> - reference
let vec_ref: &Vec<Value> = maybe_vec_ref.unwrap();
// Iter<Value> allocation
//
// pub struct Iter<'a, T: 'a> {
// ptr: *const T,
// end: *const T,
// _marker: marker::PhantomData<&'a T>,
// }
//
// .next() returns Option<&Value>
let vec_ref_iter: Iter<Value> = vec_ref.iter();
// Map<..., ...> allocation
//
// pub struct Map<I, F> {
// iter: I,
// f: F,
// }
//
// .next() returns Option<u64>
let vec_ref_iter_map: Map<Iter<Value>, fn(&Value) -> u64> =
vec_ref_iter.map(|x: &Value| x.as_u64().unwrap());
// Nothing happens till this point. I mean, only Iter, Map, ... structures
// were allocated. But because they're lazy, we have to consume the last
// Map (vec_ref_iter_map) to fire the whole machinery.
//
// What's going on (simplified)?
//
// * Vec implements FromIterator
// * vec_ref_iter_map implements Iterator
// * FromIterator consumes vec_ref_iter_map.next() till None (= end)
// * vec_ref_iter_map.next() returns Option<u64>
// * it internally gets vec_ref_iter.next() value
// * if value is None then None is returned (= end)
// * if value is Some(x) then it applies .map() closure (x.as_u64().unwrap())
// and returns Some(closure result)
//
// The only allocated Vec here is the last one (numbers). No other Vectors
// were allocated.
let numbers: Vec<u64> = vec_ref_iter_map.collect();
println!("{:?}", numbers);
}
文档: