Rust: 基本语法
Rust基本语法
语句和表达式
通用规则
语句是不会返回值的命令;表达式是会返回值的命令
如果一个表达式后接
';',那么它只是一个语句而不是表达式 相反,rust允许一个命令不接';',这时这条命令是一条表达式 许多函数是可以作为表达式(不加分号),也可以作为语句的块表达式:可以用
{}包围一系列语句及最后接一个表达式,方便推理,块表达式会返回最后这个表达式的返回值1
2
3
4let a: i32 = {
let b: i32 = 1; // 推理
b + 1 // 块表达式返回值
};
控制流语句或表达式
1
2
3
4if <bool型表达式> {
} else if <bool型表达式> {
} else {
}loop:无限循环表达式,直到用户通过break退出 它会返回break后跟的值,类似return ...break也可以不跟值,这时loop块是一条语句1
for <可变变量> in <range> {}
其中
<range>可用类似1..=10的语法糖快速创建
变量所有权
RAII:类似
java,标识符是一个在栈上的引用,指向常量池或堆上的值针对常量池中的值(例如整型、常量字符串):赋值相当于将常量的引用赋给变量,若赋给多个变量,则它们的引用均指向这个常量
针对堆上的值:每一个值都有一个所有者,且任意时刻只有一个所有者;这是为了摒弃
GC做出的和其它语言的区别:一个值只能有一个引用,使用时只能转让或自动退出时被drop当变量离开作用域时,值会被丢弃; 经过赋值操作时,值会被转移;也就是说,一个变量通过赋值将值绑定给另一个变量时,前者这个变量就不再拥有这个值1
2let s1 = String::from("hello");
let s2 = s1; // s1不再拥有上述创建的"hello", 而s2和"hello"绑定
rust和其它语言通过垃圾回收(java)或程序员手动分配(C/C++)内存不同,它通过所有权系统管理内存- 在编译时检查程序是否违反所有权机制,这也是容易编译不通过的原因
- 所有权机制是在编译时起作用的,不像垃圾回收那样,会对性能产生负面影响
数据类型
定义标识符
指定数据类型:
rust虽然支持对变量自动识别类型,但毕竟是强类型语言,最好手动指定数据类型,语法为<变量名>: <数据类型> = <值>定义变量:
let <变量名>:定义不可变变量(第一次绑定值后只读,且只允许通过let再次声明后重新绑定值)let mut <变量名>:定义可变变量- 变量在声明时可以不绑定值,但此时必须指定数据类型
定义常量:
const <变量名>: type = value- 必须手动指定数据类型,并在声明时绑定值
定义静态变量:
static定义引用:所有类型都有引用类型,这个引用不同于
java、python的引用,而更像C/C++的轻量级引用1
2let a = &oth_obj; // oth_obj的只读引用
let a = &mut oth_mutable_obj; // oth_mutable_obj的可变引用, 要求oth_mutable_obj为可变变量在整个作用域中,只允许最多一个可变引用 结合一个标识符会在作用域结束时释放,可以实现类似以下的操作:
1
2
3
4
5let mut obj = Box::new(10);
{
let ref1 = &mut obj;
} // ref1释放
let ref2 = &mut obj; // 如果替换它们的顺序, 是不允许的关于函数参数:这个引用类型比
C++更严格,想传递一个引用参数的话,形参的类型必须为对应的引用类型变量名风格:
snake case规范(所有字母小写,用下划线分隔单词)
基本数据类型
- 整型:
i8、i16、...:有符号整型u8、u16、...:无符号整型isize、usize:自适应有/无符号整型
- 字符型:
char:Unicode字符str:基本不会用到的字符串类型,因为是DST
类与函数
函数
fn <函数名> (<函数参数>) -> <返回值类型> {<函数体>}在指定返回值类型后,函数体必须通过表达式或return返回指定类型的值- 闭包函数,即所谓
lambda表达式: