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的做用。

相关文章
相关标签/搜索