前言
笔者在初学Rust时,感觉其和C语言的语法底层比较类似,尤其是;、{} 这类的符号。仔细了解底层表达式之后,才知道其有很大的不同。本文章讲通过类比方法,来仔细说明两个代码的底层原理的不同。
注意这里的底层原理类似自然语言的语法,主谓宾结构等,而不是编译运行或者内存堆栈等底层原理。主要提供一个编译器解析代码的视角,从而帮我们理解代码的构成。
C语言的语法语意
C语言作为一个基础语言,其核心语法语义非常简洁,除开预编译#define等命令外,其他语句的核心基础就是用;分开的每一句语句。
其中包括如下内容:
- 定义语句
int a; - 表达语句
a + b; - 赋值语句
i = 3; - 调用语句
add();
然后为了能让程序做到条件,循环等结构,C语言定义了类似for, while, if, else, return, break等关键字,同时还使用{}来包住代码块来将多条语句作为一条语句被关键字使用。
比如if关键字接受一个bool,然后根据bool的值来运行后面的一条语句。再由{}扩展开成一段条件代码。
if (i>0) {
// 下面是用;分开的多行代码
}
C表达式的返回值
C的核心语法中,除了定义语句外,其他三个语句都会有对应的值,比如表达式1 == 1返回TRUE/1;i = 3返回3;add();返回对应函数的返回值。而代码块和关键字等语句没有返回值。
用一句话总结就是C语言的表达式有值,而for等语句没有值。
Rust语言的表达式
而Rust语言进一步扩展了表达式,C语言里面作为语句的内容,都可以被看作是表达式,也就是能返回值。比如下列的if语句。
if i <= 10 {
i = i+1
} else {
i = i-1
};
这一整段和C的不同在于,{}内不再有;。而最后的括号后多了一个分号,原因是因为C语言把这段话作为if为关键字的语句,代码块中有其他子语句构成所以需要{}中间需要分号,而结尾不需要分号。而rust这一整段不是语句,而是表达式,所以最后结尾是一个分号。同时这个表达式也有返回值,返回值为i+1或者i-1。
因此C语言的三元运算符?不再是被需要的。
块表达式
{}在rust中不再是语句块,也是一个表达式。其返回其中语句的值。
let a = {
b=1;
c=1;
b+c
};
此时{}中的分号有点类似于C的逗号a = (b = 1, c = 1, b + c);
Rust的分号
在Rust中,分号的作用为:
- let表达式必须要分号
let a = 1; - 调用方法,丢弃返回值。
foo(); - 无分号的表达式回将返回值向外传递
例如下列例子将会编译不通过:
if i>1 {
add(i, i)
}
因为没有分号,add语句的返回值会往{}外传递,但是因为没有else的if语句必定返回(),所以会报错。
其他表达式
以此类推,包括match,while等等其他语句,也都作为表达式而存在,甚至闭包和迭代器也属于这一类,只是略显深奥。
