rust语法备忘
1.表达式
1.1 赋值表达式返回的类型为unit,即一个空的tuple()。这样设计就可以防止连续赋值,在Rust中是不允许连续赋值的。把赋值表达式的返回值类型规定成了一个unit的话,那么就可以防止连续赋值了,因为会报类型错误。
1.2 语句返回的类型是()。
1.3 Rust程序是由表达式组成的,而表达式肯定有一个返回值,顺序执行。所以下面这样写是OK的:
1 | let y: i32 = {println!("hello"); 5}; |
1.4 Rust规定if和else以及else if后续的语句块一定要用大括号包起来。相反,条件表达式并不需要用小括号包起来。
1 | let a: i32 = if condition {1} else {10}; // 注意并没有加分号 |
如果把if-else作为表达式使用的话,那么需要注意if分支以及else分支所返回的类型必须是相同的,并且在Rust编译器眼中,如果忽略了else语句的话,那么默认就是返回(),因此像下面这样写一定是错误的:
1 | let a: i32 = if condition {1}; // wrong , if分支和else分支所返回的类型不匹配 |
1.5 loop语句块是一定会被执行的,而while语句块需要根据表达式在运行阶段的值来决定,但是Rust又是一门在编译期做了很多静态分析的语言,于是造成了以下结果:
1 | let a: i32; |
上面这种写法是可行的,因为编译器能够通过流程分析出a=1;一定在println a之前执行过,所以不会报错。在Rust中,没有自动赋值这一说,声明而已。但是下面这样写就会报错了:
1 | let a: i32; |
1.6 在Rust中,每一个函数都具有自己单独的类型,但是这个类型可以自动转换到fn类型。
1 | fn add1(t: (i32, i32)) -> i32 { |
虽然add1函数和add2函数具有一样的参数数量以及参数类型和返回值类型也是一样的,但是因为每一个函数都具有自己单独的类型,所以报错。修复方案是让func的类型是通用的fn类型即可,因为每个函数的类型可以自动转换到fn类型。像下面这样写修复都是OK的:
1 | let mut func = add1 as fn((i32, i32)) -> i32; // 或者像下面这样写也是OK的 |
上面这种方案也只是适用于函数的参数类型以及参数数量是一样的场合。
7.发散函数:发散函数返回发散类型,发散类型使用!表示,发散类型可以被转换成任意一种类型。发散类型在分支语句中可以发挥用处(因为rust要求分支语句必须返回同一种类型值),如下所示:
1 | fn out(n: i8) -> i32 { |
8.main函数:rust对于main函数的设计不同于其他语言,运行程序时候所传递的参数并不通过main函数的参数来传递,而是被保存在std::env::args()里面,如下所示:
1 | // 1.rs |
每个被空格分开的字符串都是一个参数;进程可以在任何时候调用std::process::exit()直接退出。