文档章节

Rust基础笔记:Getting input from the console

这里好像没有人
 这里好像没有人
发布于 2017/01/07 14:54
字数 1042
阅读 29
收藏 0

一个例子

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

© 著作权归作者所有

这里好像没有人
粉丝 0
博文 12
码字总数 6316
作品 0
浦东
程序员
私信 提问
Rust基础笔记之浅谈Ownership

写在前面 Ownership System是Rust中最独特和吸引人的特性,Rust也是依靠这个特性来实现他的最大的目标:内存安全,所有Rust的开发者都应该详细了解它。 多么浓厚的翻译味道,的确本人学习Rus...

junanhonglei
2016/03/16
29
0
JavaScript学习笔记整理(二)

编码,解码,网址在提交或者百度搜索的时候会将汉字进行编码,在发送. 同样的,也可以进行把编码返回成原始 var kword="郝晓宇"; var url="http://www.baidu.com/s?wd="; //对非法字符编码为单字...

weixin_36171533
2017/11/25
0
0
jQuery学习笔记(三)js中的动画效果

Document

weixin_36171533
2017/12/03
0
0
2017 我的技术之路:不忘初心,夯实基础

2017 我的技术之路:不忘初心,夯实基础 又一年春去冬来,到了年末盘点的时候,感觉自己今年相较于前两年沉稳了些,也愈能明晰自身的不足;所以本年的主题就定为了不忘初心,夯实基础。今年年...

2017/12/27
0
0
tickbh/tdengine

TDEngine a game server for rust + lua How to run git clone https://github.com/tickbh/tdengine.gitcd tdenginecargo build ##dependence redis server mysql server and then modify co......

tickbh
2016/05/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

android6.0源码分析之Camera API2.0下的Preview(预览)流程分析

本文将基于android6.0的源码,对Camera API2.0下Camera的preview的流程进行分析。在文章android6.0源码分析之Camera API2.0下的初始化流程分析中,已经对Camera2内置应用的Open即初始化流程进...

天王盖地虎626
11分钟前
0
0
java 序列化和反序列化

1. 概述 序列恢复为Java对象的过程。 对象的序列化主要有两 首先我们介绍下序列化和反序列化的概念: 序列化:把Java对象转换为字节序列的过程。 反序列化:把字节序列恢复为Java对象的过程。...

edison_kwok
23分钟前
0
0
分布式数据一致性

狼王黄师傅
今天
1
0
经验

相信每位开发者在自己开发的过程中,都会反思一些问题,比如怎样提高编程能力、如何保持心态不砍产品经理、996 之后怎样恢复精力……最近开发者 Tomasz Łakomy 将他 7 年的开发生涯中学习到...

WinkJie
今天
4
0
从源码的角度来看SpringMVC

SpringMVC核心流程图 简单总结 首先请求进入DispatcherServlet 由DispatcherServlet 从HandlerMappings中提取对应的Handler 此时只是获取到了对应的Handle,然后得去寻找对应的适配器,即:H...

骚年锦时
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部