我正在使用 serde_json 反序列化 json 文档。我有一个函数,给定一个字符串(这是 json 文档),将返回一个 serde_json 值(这是一个表示 json 类型的枚举),返回一个选项。该值会根据需要传递给其他函数。
但是,我意识到传递值并不是我想要的,因为这样做,密钥不可用。
为了说明我的观点,如果我有一个如下所示的 json 文档:
{
"root" : {
"regex" : null,
"prefixes" : [ "a_", "b_" ]
}
}
“root”是一个 json 对象,“regex”是 json Null,“prefixes”是一个 json 数组。
现在,json 类型 Value 是一个枚举,带有表示 json 类型的鉴别器,例如上面给出的示例的 Object、Null、Array。
serde_json crate 使用 std::collections::BTreeMap 来表示 json 文档中的节点,其中 String 类型表示 json 键(在上面,这些将是“根”、“正则表达式”和“前缀”。所以传递只是对 Values 的引用只是部分有用,我应该改为传递 BTreeMap ,这样我也可以访问密钥。
所以这是我试图重写的以下函数:
fn get_json_content(content_s : &str) -> Option<Value> {
// instead of returning a value, we need to return a BTreeMap, so we can get the
// key and the value.
println!("===>>> json_content obtained: {}", content_s);
match serde_json::from_str(content_s) { // -> Result<Value>
Ok(some_value) => Some(some_value),
Err(_) => None
}
}
所以我开始重新编写函数,但遇到了“在这个上下文中必须知道这个值的类型”错误:
fn get_json_content_as_btreemap<'a>(content_s : &str) -> Option<&'a BTreeMap<String, Value>> {
match serde_json::from_str(content_s) { // -> Result<Value>
Ok(some) => {
// I expect the type of key_value_pair to be BTreeMap<String, Value>>
// (but I may be wrong!)
let key_value_pair = some.as_object().unwrap(); // Error here
},
Err(_) => None
}
}
我在stackoverflow上发现了其他类似的问题: 这个值的类型必须在这个上下文中是已知的
并将其用作助手,我尝试按如下方式插入类型:
let key_value_pair = some.as_object::<BTreeMap<_, _>>().unwrap();
这不能解决问题。此外,尝试了其他类似的变化无济于事。那么我该如何解决这个问题?
编辑:
我在这个应用程序中有另一个功能如下:
fn get_root_value<'a>(json_documemt : &'a Value) -> Result<&'a Value, JsonErrorCode> {
if json_documemt.is_object() {
for (k, v) in json_documemt.as_object().unwrap().iter() {
if k == "root" {
println!("found root: {}", k);
return Ok(v)
}
}
return Err(JsonErrorCode::Custom("Failed to find root node".to_string()))
}
Err(JsonErrorCode::Custom("Not an object".to_string()))
}
...这工作正常。在这里你可以看到我可以调用 as_object() ,然后以元组对的形式获取键和值。我不明白为什么 as_object 在一种情况下有效,而在另一种情况下无效。我想拉出 BTreeMap 并将其作为借来的项目传递。