Rust基礎筆記:Getting input from the console

一個例子

Rust能和其餘編程語言同樣從控制檯得到用戶輸入,但Rust的處理方式確和其餘語言有着很大的區別,這其中有着不少值得學習和思考的東西。
從一個小例子開始:html

let mut buf = String::new();
    io::stdin().read_line(&mut buf);

分析

先來看看手冊中 io::stdin() 返回了什麼:
這裏寫圖片描述golang

Stdin是一個結構體,並實現了一個叫read_line()的方法,這個方法是這個樣子的:
這裏寫圖片描述
它的工做就是從控制檯中讀取一行用戶輸入,並寫入buf中,編譯一下,並無出錯,而是給出了一個警告:編程

warning: unused result which must be used, #[warn(unused_must_use)] on by default

因而可知咱們的工做並無完成,由於read_line()方法並無直接返回讀取的長度,而是用Rusult將這個長度值包裹起來了,這是爲何呢?安全

由於從安全的角度來講,從控制檯中獲取輸入,可能成功也能夠失敗,而read_line()的返回值Result就包含了成功和失敗的兩種可能,必需要對其處理,先來看看Result的結構:(https://doc.rust-lang.org/stable/std/result/enum.Result.html編程語言

enum Result<T, E> {
        Ok(T),
        Err(E)
    }

正確的結果會被包含在Ok中,出錯則返回Err,Result已經實現了相關判斷函數好比is_ok(),is_err(),這裏強調一下ok()和err()方法,看手冊:函數

這裏寫圖片描述

從文檔中能夠看出來,若是Result的結果是正確的,那麼就將它轉換成Option::Some,若是它是錯誤的,就將它轉換成Option::None,通過ok()的轉換之後,前面的處理中對和錯的結果就被轉換成了期待的數據和空兩種形式,在上面的小例子中,若是沒有出錯,數據就會存到buf中去,若是失敗了呢?那就只能提示出錯了,下面來看看,在這最後一步的錯誤處理中如何操做。學習

在前面的說明中ok()方法返回了一個Option,在這個例子中,咱們只須要處理Option::None就能夠了,也是就是說,若是這裏爲None的話,那麼buf裏也就什麼也沒有得到,提示出錯就行了。spa

先來看看Option這個enum (參照文檔:https://doc.rust-lang.org/stable/std/option/enum.Option.html).net

enum Option<T> {
       None,
       Some(T),
    }

它呢,和Result差很少,而咱們用到的是一個它已經實現的方法,叫作:expect(),文檔中聲明以下:code

這裏寫圖片描述

也就是說,它會判斷這個Option是Some仍是None,若是是Some,它就會取出其中的T並返回,若是遇到了None,那麼就出錯,並將參數中的字符串做爲錯誤消息打印出來。

這個時候,來個完成的程序,總結一下:

use std::io;
    fn main() {
        let mut buf = String::new();
        println!("Please input your name:"); // 這行輸出須要包含一個換行符,不然要等到你輸入完後才能看見
        io::stdin().read_line(&mut buf).ok().expect("Error!");
        println!("Hello {} !", buf);
    }

額~輸出是這樣的:

這裏寫圖片描述

怎麼跑到下面去了,緣由是:
緣由是咱們剛纔的輸入中包含了一個回車符,Rust連同這個換行符一併放到了buf中,這顯然不是咱們想要的,因此咱們在這裏應該處理一下這個回車符,接着上面的代碼:

let name = buf.trim();
    println!("Hello {} !", name);

trim方法很簡單,和大多數其餘語言中的trim函數同樣,就是去掉字符串兩邊多餘的字符,參見
https://doc.rust-lang.org/stable/std/string/struct.String.html#method.trim

重新編譯,結果就正常啦:
這裏寫圖片描述

整理一下:

use std::io;
    fn main() {
        let mut buf = String::new();
        println!("Please input your name:");
        io::stdin().read_line(&mut buf).ok().expect("Error!");
        let name = buf.trim();
        println!("Hello {} !", name);
    }

小結

從上面的代碼看到,咱們自始至終都沒有使用相似golang中處處都是if err的處理方式,全部的操做在一行內通通完成,是否是很是優雅,在這其中Result和Option扮演了很是重要的角色,在Rust有許許多多這樣的使用方式,須要好好理解這兩個enum的做用。

相關文章
相關標籤/搜索