Rust语言圣经13 - 语句与表达式

Posted 编程学院

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rust语言圣经13 - 语句与表达式相关的知识,希望对你有一定的参考价值。

原文链接:https://course.rs/basic/base-type/statement-expression.html
 
欢迎大家加入Rust编程学院,中国最好的Rust学习社区

  1. 官网:https://college.rs
  2. QQ群:1009730433

语句和表达式

Rust的函数体是由一系列语句组成,然后最后由一个表达式来返回值,例如:

fn add_with_extra(x: i32, y: i32) -> i32 
    let x = x + 1; // 语句
    let y = y + 5; // 语句
    x + y // 表达式

语句会执行一些操作但是不会返回一个值,而表达式会在求值后返回一个值,因此在上述函数体的三行代码中,前两行是语句,最后一行是表达式。

对于Rust语言而言,这种基于语句和表达式的方式是非常重要的,你需要能明确的区分这两个概念, 但是对于其它很多语言而言,这两个往往无需区分。基于表达式是函数式语言的重要特征,表达式总要返回值。

在此之前,我们已经多次使用过语句和表达式, 先从语句讲起:

语句

let a = 8;
let b: Vec<f64> = Vec::new();
let (a, c) = ("hi", false);

以上都是语句,它们完成了一个具体的操作,但是并没有返回值,因此是语句。

由于let是语句,因此不能将let语句赋值给其它值,如下形式是错误的:

let b = (let a = 8);

错误如下:

error: expected expression, found statement (`let`) // 期望表达式,确发现`let`语句
 --> src/main.rs:2:13
  |
2 |     let b = let a = 8;
  |             ^^^^^^^^^
  |
  = note: variable declaration using `let` is a statement `let`是一条语句

error[E0658]: `let` expressions in this position are experimental // 下面的`let`用法目前是试验性的,在稳定版中尚不能使用
 --> src/main.rs:2:13
  |
2 |     let b = let a = 8;
  |             ^^^^^^^^^
  |
  = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
  = help: you can write `matches!(<expr>, <pattern>)` instead of `let <pattern> = <expr>`

以上的错误告诉我们let是语句,不是表达式,因此它不返回值,也就不能给其它变量赋值。但是该错误还透漏了一个重要的信息,let作为表达式已经是试验功能了,也许不久的将来,我们在stable rust下可以这样使用。

表达式

表达式会进行求值,然后返回一个值。例如5 + 6,在求值后,返回值11,因此它就是一条表达式。表达式可以成为语句的一部分,例如let y= 6中,6就是一个表达式,它在求值后返回一个值6(有些反直觉,但是确实是表达式),调用一个函数是表达式,因为会返回一个值,调用宏也是表达式,用花括号包裹最终返回一个值的语句块也是表达式,总之,能返回值,它就是表达式,无论简单还是复杂。例如:

fn main() 
    let y = 
        let x = 3;
        x + 1
    ;

    println!("The value of y is: ", y);

其中我们把一个语句块表达式的值赋给了y,语句块长这样:


    let x = 3;
    x + 1

该语句块是表达式的原因是:它的最后一行是表达式,返回了x + 1的值,注意x + 1不能以分号结尾,否则就会从表达式变成语句, 表达式不能包含分号。这一点非常重要,一旦你在表达式后加上分号,它就会变成一条语句,再也不会返回一个值,请牢记!

以上是关于Rust语言圣经13 - 语句与表达式的主要内容,如果未能解决你的问题,请参考以下文章

Rust语言圣经07 - 变量绑定与解构

Rust语言圣经11 - 引用与借用

Rust语言圣经12 - 字符串与切片

Rust语言圣经28 - 深入类型转换

Rust语言圣经33 - HashMap

Rust语言圣经26 - 特征对象