簡體   English   中英

錯誤:必須在此上下文中知道此值的類型(Rust)/ serde_json值

[英]error: the type of this value must be known in this context (Rust) / serde_json Value

我正在使用serde_json反序列化json文檔。 我有一個函數,給定一個字符串(這是json文檔),將返回一個serde_json值(這是一個代表json類型的枚舉),返回一個Option。 該值將根據需要傳遞給其他函數。

但是,我意識到傳遞一個值並不是我想要的,因為這樣做,鍵不可用。

為了說明我的觀點,如果我有一個像這樣的json文檔:

{
  "root" : {
    "regex" : null,
    "prefixes" : [ "a_", "b_" ]
  }
}

“ root”是json對象,“ regex”是json Null,“ prefixes”是json數組。

現在,json類型的Value是一個枚舉類型,該標識符帶有表示json類型的標識符,例如上面給出的示例的Object,Null,Array。

serde_json板條箱使用std :: collections :: BTreeMap表示json文檔中的節點,其中String類型表示json鍵(在上面,它們是“ root”,“ regex”和“ prefixes”。因此,傳遞僅僅引用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並將其作為借來的項目傳遞出去。

您可以更改初始函數的返回類型,如果可以, serde_json將反序列化為相應的對象:

fn get_json_content(content_s : &str) -> Option<BTreeMap<String, 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
    }    
    // Note: this match statement can be rewritten as
    // serde_json::from_str(content_s).ok()
}

第二個示例將不起作用,因為您正在實例化函數內的Value對象,然后嘗試返回對剛實例化的對象的引用。 這將行不通,因為該對象將在函數末尾超出范圍,然后引用將無效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM