Rust 2.5 if
10 Jan 2015 by LelouchHe
Rust的if
并不是很复杂,但它更像是动态语言中的if
,而不是传统的系统编程语言中的那样.所以,我们下面介绍它,体会下其中的区别.
if
是一个更广泛概念”branch”的特殊形式.名字来源于树枝(“branch in a tree”): 一个决策判断点,不同的选择带来不同的分支走向.
一种情况下,一个选择带来2个分支:
let x = 5;
if x == 5 {
println!("x is five!");
}
如果改变了x
的值,就不会输出那句话了.具体而言,如果if
后面的表达式为真(true),语句执行,否则,就不执行.
如果非真(false)的时候,要执行某些语句的话,使用else
:
let x = 5;
if x == 5 {
println!("x is five!");
} else {
println!("x is not five :(");
}
这些都很常规.然而,你还可以这样做:
let x = 5;
let y = if x == 5 {
10
} else {
15
}; // y: i32
我们也可以这样来写(这样更好):
let x = 5;
let y = if x == 5 { 10 } else { 15 } // y: i32
这说明了2点: Rust是基于表达式(expression-based)的语言;分号(“;”)和其他基于大括号与分号的语言不同.这2点是相关的.
表达式(expression)与语句(statement)
Rust是基于表达式的语言.除了2种语句类型之外,其他都是表达式类型.
他们的区别是什么?表达式返回一个值(value),但语句不返回.很多语言里,if
是一个语句,所以类似let x = if ...
是没有意义的.但在Rust中,if
是表达式,会返回值.我们就是用这个值来初始化y
的绑定的.
另外,绑定是Rust的2种语句之一.正式的名字应该是声明语句(declaration statement).到目前为止,let
是唯一一种声明语句.我们再来看看其他的.
很多语言里,变量绑定被当作表达式,而不是语句.比如Ruby中:
x = y = 5
但在Rust中,使用let
来进行绑定不是一个表达式.以下写法会导致编译错误:
let x = (let y = 5); // expected identifier, found keyword `let`
编译器告诉我们它预期看到一个表达式,但let
只能是语句,而不是表达式.
注意,对一个已经绑定的变量赋值(比如 y = 5)仍然是一个表达式,虽然这个表达式的值不是很有用.不像C语言,在C语言中,赋值表达式的值是被赋值的值(比如刚才那个例子里的5),但在Rust中,赋值表达式返回的是unit类型()(我们稍后会讲)(译者: 这个类型就是”()”,叫做unit类型)
第二种语句是表达式语句(expression statement).主要是讲表达式转变为语句.具体来说,Rust的语言是一条语句接一条语句的.这就是说,我们使用分号(“;”)来把表达式分隔开来.Rust很像那些要求每句结尾都用分号隔开的语言,而且你在几乎每行Rust代码后,都会看到分号的存在.
为什么是”几乎”呢?其实,你刚才已经看到了:
let x = 5;
let y: i32 = if x == 5 { 10 } else { 15 };
注意,我在这里添加了类型标注,说明y的类型需要是整型.
这个和下面这个是不同的,下面这个会编译失败:
let x = 5;
let y: i32 = if x == 5 { 10; } else { 15;};
注意10和15后面的分号.Rust会显示如下错误:
error: mismatched type: expected `i32`, found `()`
我们预期类型是整型,但却得到了().()类型读作”unit”类型,是Rust类型系统中一个特殊类型.Rust中,()不能赋值给的i32
的值.()只能赋值给()类型的变量,所以不是很有用.还记得我们说过语句不返回值么?这就是这个类型的作用了,分号将任意表达式转变为语句,丢弃掉返回值,并返回unit类型.
还有一个地方你在行尾看不到分号,那就是下一节内容: 函数