2015-12-11 4 views
2

Итак, я просмотрел 90% урока по Rust, и я думаю, что в основном я понимаю синтаксис. Я пытаюсь начать писать код с ним. В настоящее время я использую библиотеку rustc_serialize для разбора JSON от stdin, и я не получаю ожидаемых результатов. Я следующий файл JSON называется message.txt следующего содержания:Использование rustc_serialize и получение строк без кавычек

{"text": "hello world"} 

Вот код Rust принять 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 отлично подходит для быстрого прототипирования, но я бы упущением в не показывая чуть более идиоматических способ сделать это:

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); 
} 

Игнорируя Result от read_to_string хуже паниковать.^_^

+1

'let() =' трюк велик, это, вероятно, хорошо известно, но я тоже начинаю с Rust, и это удобно. –

+1

'let() =' это потрясающий трюк! Спасибо! Кроме того, очень ценю идиоматический синтаксис и великое объяснение. Когда вы говорите 'Display', это означает [этот признак] (https://doc.rust-lang.org/std/fmt/trait.Display.html)? – glenbot

+0

@glenbot yup. Я также отредактировал эту ссылку в своем ответе. :-) – Shepmaster

Смежные вопросы