Rust基础笔记:Getting input from the console

一个例子

Rust能和其他编程语言一样从控制台获得用户输入,但Rust的处理方式确和其他语言有着很大的区别,这其中有着很多值得学习和思考的东西。
从一个小例子开始:

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

分析

先来看看手册中 io::stdin() 返回了什么:
这里写图片描述

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里也就什么也没有获得,提示出错就好了。

先来看看Option这个enum (参照文档:https://doc.rust-lang.org/stable/std/option/enum.Option.html)

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

它呢,和Result差不多,而我们用到的是一个它已经实现的方法,叫做:expect(),文档中声明如下:

这里写图片描述

也就是说,它会判断这个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的作用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值