- Published on
Rust入门笔记(二)
- Authors
- Name
- Et cetera
Rust 变量常量&数据类型
let
声明变量
Rust 使用 变量就先不陈述了,老生常谈,学习各种语言都会说一遍变量
使用 let
声明的变量默认是不可变的
fn main() {
let band = "one ok rock";
band = "aimyon";
}
上侧代码cargo run
会报错如下(当然还有个问题,就是 band 变量声明但未使用)
mut(mutable)
关键字
解决方法:使用fn main() {
let mut band = "one ok rock";
// 同时字符串占位这方面类似于 Python
println!("hello {}", band);
band = "aimyon";
println!("hello {}", band);
}
声明而未使用的变量
fn main() {
// let mut singer = "aimyon";
// cargo run/build 会提示singer变量声明未使用
// 所以rust支持给变量加 _ 忽略
let mut _singer = "aimyon";
}
const
声明)
变量与常量(使用- 常量:常量在绑定值以后也是不可变的,但是他与不可变的变量有很多区别:
- 不可以使用
mut
关键字,常量永远不可变 🙅 - 声明常量使用
const
关键字,同时必须标注类型 - 常量可以在任何作用域内进行声明,包括全局作用域
- 常量只可以绑定到常量表达式,无法绑定到函数的调用结果或只能在运行时才能计算出的值
- 不可以使用
- 在程序运行期间,常量在其声明的作用域内一直有效
- 命名规范:所有字母大写,每个单词使用下划线
_
分割
shadowing(Rust 语言圣经中翻译为:变量遮蔽,个人喜欢这种翻译)
可以使用相同的变量名声明新的变量,新的变量就会 shadow(遮蔽)之前的同名变量
fn main() { // let x = 10969; // let x = 3636; // // 如果这样写 虽然后一个x已经遮蔽第一个x,但是rust会提示第一个x为使用 // println!("This number is {}", x); let x = 10969; let x = x + 3636; printli!("This number is {}", x); }
- 在后续的代码中这个变量名代表的就是新的变量
⚠️ 但是 ⚠️
shadow
和使用mut
关键字的变量重新赋值不同:- 给未使用
mut
关键字用let
声明的变量重新赋值,会导致编译错误 - 而使用
let
声明的同名新变量(shadow 后的新变量)也是不可变的 - 使用
let
声明的同名新变量的类型可以和之前的不一样
fn main() { let vari = "vari"; // vari: &str let vari = vari.len(); // vari: usize,因为len()返回一个整数 println!("variable {}", vari) }
- 给未使用
数据类型:
标量和复合类型
Rust 是静态编译语言,在编译时必须知道所有变量的类型
- 基于使用的值,编译器通常能够推断出它的具体类型
- 但如果可能的类型比较多(例如入门(一)中猜数游戏使用的将 String 转为整数的 parse 方法),必须添加类型的标注,否则编译会报错
fn main() { {/* 因为parse返回类型Reasult 有error 所以必须使用expect对error情况处理 */} {/* 因为42能用很多类型u32 i32等表示,所以如果不标注类型会报错 */} let guess:u32 = '42'.parse().expect("It's not a number"); {/* type annotations needed */} {/* let guess = '42'.parse().expect("It's not a number"); */} println!("This number is {}", guess); }
标量
一个标量代表一个单个的值
Rust
中有四个主要的标量类型:整数类型
整数类型没有小数部分
例如上面例子中的 u32 就代表一个无符号的整数类型,占据 32 位空间
无符号整数类型以 u 开头,有符号以 i 开头
rust 整数类型分类,如下图
isize
和usize
由计算机的具体架构决定,比如 windows 目前基本都是 x64 位系统,所以自然就是能用表示 64 位字节表示数字- 主要使用场景:对某种集合进行索引操作
整数字面值:
- 除了 byte 类型外,所有的数字字面值都允许使用类型后缀,如:57u8
- 如果不清楚使用哪种类型,可以直接使用 Rust 默认类型
- 整数的默认类型就是 i32:即使在 64 位系统下,速度也是很快的
整数溢出:
浮点类型
f32
单精度浮点类型f64
双精度浮点类型(默认类型,因为和 f32 速度差不多,精度更高)- Rust 的浮点类型使用 IEEE-754 标准
字符类型
布尔类型
true
false
- 一个字节大小
复合类型
复合类型可以将多个值放在一个类型里
Rust 提供了两种基础的复合类型:
Tuple
、Array
Tuple
Tuple
定义:Tuple
可以将多个类型的多个值放在一个类型里Tuple
里每个元素的类型可以不一样Tuple
长度是固定的,一旦声明无法改变
Tuple
创建:小括号中,将值用逗号分开
Tuple
中的每个位置都对应一个类型,Tuple
中各元素的类型不必相同
Tuple.rsfn main() { let tup: (i32, f64, u8) = (3636, 3.14, 69); {/* 解构赋值 */} let (x, y, z) = tup println!("{}, {}, {}", x, y, z); {/* 访问tuple元素的方法 */} println!("{}, {}, {}", tup.0, tup.1, tup.2); }
Array
Array
定义:Array
也可以将多个值放在一个类型里Array
每个元素的类型必须是一样的Array
的长度也是固定的
Array
创建:- 中括号中,用逗号隔开(和 JS 一样)
Array.rsfn main() { let arr:[i32; 4] = [1, 2, 3, 4]; println!("{}", arr); }
- 另一种声明数组的方法:
- 如果数组的每个元素值都相同,那么可以:
- 在中括号里指定初始值
- 然后是一个
;
- 最后是数组的长度
- 例如:
let arr = [36; 5];
就相当于let arr = [36, 36, 36, 36, 36]
- 如果数组的每个元素值都相同,那么可以:
用处:
- 当你想要把你的数据存放在 stack 上而不是 heap 上,或者想保证有固定数量的元素,这时推荐使用数组
- 数组没有 Vector(和数组类似,但由标准库提供,但是 Vector 可以改变长度) 灵活
Array
的类型:[类型; 长度]Array
的访问:Array
是 Stack 上分配的单个块的内存- 可以使用索引来访问数组的元素
- 如果访问的索引超出了数组的范围:
- 编译会通过
- 运行会报错(panic):
Rust
不允许其继续访问相应地址的内存