我们将在这篇博客中,讨论rust的expression
概念,rust中大部分代码都通过表达式来完成。
表达式语言
C中的表达式有值,而语句没有值。rust是一个表达式语言,这个传统可以追溯到LISP。在C中if和switch都是语句。它们并不产生值;而在rust中if
和match
可以产生值。这也解释了为什么rust没有C中的三目运算符。
优先级和结合性
注意.
有最高的优先级
块与分号
块是最通用的一种表达式,一个块可以产生值在任何地方使用。
声明
一个块还可能包含任意数量的声明,最常见的就是let声明:
let name: type = expr;
这里的type和初始化是可选的;但分号是必须的。初始化前使用变量将会报错。
if 和 match
if 表达式的用法如下:
if condition1 {block1
} else if condition2 {block2
} else {blockn
}// matchmatch code {0 => println!("hello"),_ => println!("h"),
}
注意match的arm应该覆盖所有情况。
if let
if let pattern = expr {block1
} else {block2
}if Some(cookie) = request.session_cookie {return restore_session(cookie);
}
loops
有四种loop表达式
while condition {block
}while let pattern = expr {}loop {}for pattern in iterable {}
注意loop是rust中的表达式,而while或for的值为()
。 除此之外,我们可以使用..
来表示一个区间,例如
for i in 0..20 {//
}
这里的0..20
实际上是std::ops::Range {start: 0, end:20}
. for 循环一般会消耗值,如果需要继续使用,那么使用引用,for str in &strs
loop的控制流
loop {let a = 1;break a; // 返回值
}let res = 'outer: loop {'inner: loop {if {break 'outer a; // 直接break外层的loop}}
}
return 表达式
rust中不需要显式的return表达式,可以放弃正在进行的工作
为什么需要loop
在rust中,我们有一个特殊的类型!
,表示表达式不能正常完成。
fn exit(code: i32) -> !
函数调用与方法调用
一个需要注意的是在函数调用或是方法调用中,generic的通常语法并不能work,
return Vec<i32>::with_capacity(1000); // errorlet ramp = (0..n).collect<Vec<i32>>(); // error
这里的<
都被识别为小于号;所以最好写成Vec::<i32>
.
fields和elements
type casts
存在一些自动转换的case:
String
类型的值可以转为&str
&Vec<i32>
->&[i32]
这被称为deref coercions;主要的目的是让智能指针的类型可以尽可能像其底层值那样操作。