ex13: Statement 与 Expression

这一章我们需要说明一些与编译器有关的内容,如果你没有学过“编译原理”的话你可能对本节的内容只有一个模糊的认识。不过没有关系,这一章不要求任何的掌握,只要能够有所了解就行了。

statement

我们在写程序的时候可能会从一个程序员——一个人的角度来看待所有的代码,比如说这一段是一个函数,这一行是一个变量绑定等等。但是从机器的角度上来讲,它不会说对一个程序有一个整体上认识,而是会根据某个规则进行匹配,这个规则是定死的,这也就是为什么我们编程需要符合某些语法规定,否则写出来的程序编译器(或解释器)根本就不认识(无法进行解析)。

对于 Rust 而言,一个基本的代码块称之为一个statement。一个statement一般描述了一段完整的程序的行为,比如说进行变量绑定,我们会有以下的一个代码:

let number = 0;

这一句代码是一个固定的模式,即一个LetStatement。也就是说当你写下这段代码的时候,编译器会识别出来你所写的语句是什么含义,并且根据你写的内容进行对应的操作。

有若干种不同的statement,我们在之前的程序中经常出现的有三种:其中一个就是上面的变量绑定,由let指定的statement;另一个则是ExpressionStatement,比如说x;就是一个statement,由一个表达式和分号结尾组成;第三个则是由宏提供的,类似println!();这样的式子也是statement

block

一般来说,一个block指的是一个由大括号包围起来的区域。一个block中可以有很多的statements

{
    statement
    statement
    statement
    ...
}

我们所编写的函数也是这样的原理:

fn main() {
    let number = 10; // 一个变量绑定的 statement
    let x; // 一个变量绑定的 statement
    x = number; // 一个 expression; 组成的 statement
} // 外面的大括号是一个 block

expression(表达式)

表达式(expression)是一个非常难理解的概念,因为它种类很多,还会套来套去。

一个表达式会有两个很明显的特征:第一,它是有“值”的;第二,它会产生“效果”。这代表了一个过程的两个结果:一个表达式会在“得到它的值”的过程中“产生效果”。

不能光说不练,请看下面的代码:

fn main() {
    let a = 1;
    let b = 2;
    println!("{}", a + b);
}

println!这一行存在一个加法算式a + b,这是一个算数表达式,可以很自然地发现它的值为a+b的算数结果,在这个程序中就是 3 。

表达式的形式有非常多,比如说函数调用就是一个很典型的表达式,而block自身也是一个表达式。block的值为大括号中最后一个表达式的值,如果其没有最后一个表达式,则其值为()

那么知道了表达式又能有什么用处呢?我们来观察下面的一段代码:

fn main(){
    let x = {
        let y = 2;
        y * y
    };
}

那么这段代码是什么意思呢?我们来一点一点看:

let x = {...};这个语句是一个明显的变量绑定语句,我们还知道大括号是一个block也是一个expression,这说明大括号具有某个值,那么这个值等于什么呢?因为block的值为block中最后一个表达式的值,我们看到最后一个表达式是一个乘法语句,其结果应该为 4 ,说明这个大括号整体的值为 4 ,最后会把数值4i32绑定在变量x上。

虽然看上去花里胡哨没有什么用处,但是这个知识在后面的控制流中派上大用场。

代码

fn main() {
    let x = 2i32; // 这是一个 statement

    let y = {
        x * x // 这是一个 expression。因为没有分号所以它的值能够传递下去
    };

    let z = {
        y + 1; // 这是一个 statement,没有值。因为 expression 有分号,所以它的值无法向下传递
    };

    println!("x: {}", x); // 这些打印宏与分号的组合也是 statement
    println!("y: {}", y);
    println!("z: {}", z);
} // 大括号组成的部分是一个 block,具有值。

本节总结

本节我们针对statementexpression进行了非常基础的介绍,主要说明了expression具有值的特点。

你应该对以下的内容有所了解:

  1. 可以在代码中确定哪个是表达式,哪个是 statement

  2. 能够理解在大括号的最后写不带分号的表达式的含义

参考资料

最后更新于