2015-12-11 51 views
2

所以我已經經歷了Rust的90%的教程,我認爲我大多掌握了語法。我試圖開始用它編寫代碼我目前使用rustc_serialize庫來解析來自stdin的JSON,我沒有得到我期望的結果。我有以下的JSON文件名爲message.txt以下內容:使用rustc_serialize並獲取未加引號的字符串

{"text": "hello world"} 

這裏是鏽代碼接受stdin並解析出text領域:

extern crate rustc_serialize; 

use std::io::{self, Read}; 
use rustc_serialize::json::Json; 

fn main() { 
    // provide a buffer for stdin 
    let mut buffer = String::new(); 
    let _ = io::stdin().read_to_string(&mut buffer); 

    // parse the json 
    let message = match Json::from_str(&mut buffer) { 
     Ok(m) => m, 
     Err(_) => panic!("Stdin provided invalid JSON") 
    }; 

    // get the message object and "text" field string 
    let message_object = message.as_object().unwrap(); 
    let message_string = message_object.get("text").unwrap(); 

    println!("{}", message_string); 
    println!("{}", &message_string.to_string()[0..4]); 
} 

下面的代碼輸出:

"Hello World" 
"Hel 

我目前正在輸出字節片段,以確保報價不是通過打印添加的東西。根據文檔message_string不應該有引號。

如果我打印出來使用從文檔,然後它打印的「文本」的值的示例中的數據不帶引號:

for (key, value) in message_object.iter() { 
    println!("{}: {}", key, match *value { 
     Json::U64(v) => format!("{} (u64)", v), 
     Json::String(ref v) => format!("{} (string)", v), 
     _ => format!("other") 
    }); 
} 

輸出:

text: hello world (string) 

我是一個新手,所以我可能只是不理解Rust的字符串操作部分。

回答

7

問題是,message_string是不是你認爲它是。我發現,當我嘗試在「字符串」上使用len時,該字符串不起作用(我假設這就是爲什麼當你切片時你有一個to_string)。讓我們make the compiler tell us what it is

let() = message_string; 

有錯誤:

error: mismatched types: 
expected `&rustc_serialize::json::Json`, 
    found `()` 

這是一個Json!我們需要在該枚舉類型轉換成繩狀的東西:

let message_object = message.as_object().unwrap(); 
let message_json = message_object.get("text").unwrap(); 
let message_string = message_json.as_string().unwrap(); 

最後,我要說的卻是Display(允許{}格式字符串)應該已爲這種類型的實現,爲Display意味着以最終用戶爲中心的方式進行格式化。現在改變這個決定可能已經太晚了。


我知道unwrap是偉大的快速原型,但我會在不顯示這樣做的稍微習慣的方法是失職:忽視從read_to_stringResult是有過之而無不及

fn main() { 
    let mut buffer = String::new(); 
    io::stdin().read_to_string(&mut buffer).expect("Could not read from stdin"); 

    let message = Json::from_str(&mut buffer).expect("Stdin provided invalid JSON"); 

    let message_string = message.as_object().and_then(|obj| { 
     obj.get("text").and_then(|json| { 
      json.as_string() 
     }) 
    }).expect("The `text` key was missing or not a string"); 

    println!("{}", message_string); 
} 

恐慌。^_^

+1

'let()='技巧很棒,這可能是衆所周知的,但我也是從Rust開始的,這很方便。 –

+1

'let()='是一個了不起的竅門!謝謝!另外,真的很欣賞這種慣用的語法和很好的解釋。當你說'Display'確實意味着[這個特質](https://doc.rust-lang.org/std/fmt/trait.Display.html)? – glenbot

+0

@glenbot是。我已經將該鏈接編輯爲我的答案。 :-) – Shepmaster

相關問題