Skip to content

变量

变量可变性

默认情况下, 默认情况下变量是不可变的

当变量不可变时, 这意味着一旦一个值绑定到一个变量名后, 就不能更改该值了

rust
fn main() {
  let x = 10;
  x = 20;
  println!("x is {}", x);
}
// 这个代码是无法通过编译的, 报错信息如下:
// cannot assign twice to immutable variable `x`
rust
fn main() {
  let mut x = 10;
  x = 20;
  println!("x is {}", x);
}
// 加上 mut 关键字后, 可以通过编译
// 那就证明, 现在变量是可以重新赋值的
sh
warning: value assigned to `x` is never read
 --> main.rs:2:9
  |
2 |     let x = 10;
  |         ^
  |
  = help: maybe it is overwritten before being read?
  = note: `#[warn(unused_assignments)]` on by default

error[E0384]: cannot assign twice to immutable variable `x`
 --> main.rs:3:5
  |
2 |     let x = 10;
  |         -
  |         |
  |         first assignment to `x`
  |         help: consider making this binding mutable: `mut x`
3 |     x = 20;
  |     ^^^^^^ cannot assign twice to immutable variable

error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0384`.
x is 10

变量的遮蔽

所谓 遮蔽(shadow) 就是说: 可以声明和前面变量具有相同名称的新变量

rust
fn main() {
    let x = 10;
    println!("x is {}", x); // 10

    let x = x + 10;
    println!("x is {}", x); // 20
}

静态变量

  1. 定义静态变量时必须声明类型
  2. 静态变量是可以修改的(但是需要在 unsafe 块中)
  3. 静态变量的作用域是整个程序运行期间
  4. 不能在函数内部定义必须在模块顶部定义
rust
static APP_SLOGAN: &str = "Rust is best language";

fn main() {
  println!("{}", APP_SLOGAN);
}

常量

  • 定义常量时必须声明类型
  • 与其他编程语言类似, 常量声明后无法修改
  • 命名规范为: 字母全部大写, 以 _ 分割单词, 如: SECONDS_IN_HOUR SECONDS_IN_DAY SECONDS_IN_WEEK
rust
// 常量可以是一个值
const SECONDS_IN_MINUTES:u32 = 60;

// 也可以是一个表达式计算的值
const SECONDS_IN_HOUR:u32 = 60 * 60;

// 也可以是一个有其他常量表的达式计算的值
const SECONDS_IN_DAY:u32 = SECONDS_IN_HOUR * 24;

fn main() {
    println!("{}, {}, {}", SECONDS_IN_MINUTES, SECONDS_IN_HOUR, SECONDS_IN_DAY);
}

数据类型

查看参考手册

标量类型(scalar)

标量(scalar)类型表示单个值

整数类型 integer

长度有符号类型无符号类型
8 位i8(-128,127)u8(0,255)
16 位i16(-32768, 32768)u16(0,65535)
32 位i32(-2147483648,2147483648)u32(0, 4294967295)
64 位i64u64
128 位i128u128
archisizeusize

isizeusize 类型取决于程序运行的计算机体系结构, 在表中表示为 arch: 若使用 64 位架构系统则为 64 位, 若使用 32 位架构系统则为 32 位

最大值, 最小值计算:

  1. 有符号

    • 最小值: -(2n - 1)
    • 最大值: 2(n - 1) - 1
  2. 无符号

    • 最小值:0
    • 最大值: 2n - 1

n 代表类型后的数字, 比如 i8 最大值就是: 2(8-1)-1 => 27 - 1 => 128 - 1 => 127

rust
fn main() {
    let i8n: i8 = -10; // -128 - 127
    let u8n: u8 = 255; // 0 - 255
    println!("{i8n}, {u8n}");

    // 如果硬要将一个超过类型最大值的数字
    // 赋值给对应类型的变量, 那么就会报错
    let out_of_range_number: i8 = 200;
}
sh
error: literal out of range for `i8`
 --> main.rs:8:35
  |
8 |     let out_of_range_number: i8 = 200;
  |                                   ^^^
  |
  = note: the literal `200` does not fit into the type `i8` whose range is `-128..=127`
  = help: consider using the type `u8` instead
  = note: `#[deny(overflowing_literals)]` on by default

error: aborting due to 1 previous error; 1 warning emitted
数字字面量示例
十进制98_222
十六进制0xff
八进制0o77
二进制0b1111_0000
字节 (仅限于 u8)b'A'
rust
fn main() {
    let n = 11; // 10 进制, 没什么好说的
    println!("n is: {}", n);

    let n = 0x10; // 16 进制的 16, 0x开头
    println!("n is: {}", n);

    let n = 0o10; // 8 进制的 8, 0o开头
    println!("n is: {}", n);

    let n = 0b10; // 2 进制的 2, 0b开头
    println!("n is: {}", n);
}

浮点型 float

比 js 设计更合理的浮点数, js 单精度的浮点数设计太变态了

长度有符号类型无符号类型
32 位f32u32
64 位f64u64
rust
fn main() {
    let f1 = 1.1;
    let f2 = 1.2;
    let f3 = f1 + f2;
    println!("f3 is: {f3}"); // 2.3
}

布尔型 bool

与其他变成语言一样, 两个取值 true false

rust
fn main() {
    let is_ok = true;
    println!("is ok {is_ok}");

    let can_i_use = false;
    println!("can i use:{can_i_use}");
}

字符类型 char

  • 存储任意一个字符

注意: 表示字符类型, 只能用 '', 不能使用""

rust
fn main() {
    let char_c: char = 'C';
    println!("char_c is {}", char_c);
}

// 如果使用双赢号就报错: 类型不匹配 mismatched types
// let char_c: char = "C";
sh
error[E0308]: mismatched types
 --> main.rs:2:24
  |
2 |     let char_c: char = "C";
  |                 ----   ^^^ expected `char`, found `&str`
  |                 |
  |                 expected due to this
  |
help: if you meant to write a `char` literal, use single quotes
  |
2 |     let char_c: char = 'C';
  |                        ~~~

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.

复合类型(compound type)

元组 tuple

rust
fn main() {
    let mut tup = (false, 11, 3.14);

    // 会自动进行类型推导,多数情况不需要手动指定
    // let tup: (bool, i32, f32) = (false, 11, 3.14);

    // 与其他编程语言的元组不同的是, rust 元组的元素是可修改的
    tup.1 = 22;

    // 通过 元组.索引 获取元素
    println!("tup 0 is:{}", tup.0);
    println!("tup 1 is:{}", tup.1); // 22
    println!("tup 2 is:{}", tup.2);

    // 通过类似 js 解构的方式来获取元素
    let (x, y, z) = tup;
    println!("x is:{}", x);
    println!("y is:{}", y);
    println!("z is:{}", z);

    // 如果访问不存在的值, 就会报错
    // println!("tup 3 is:{}", tup.3);
}
sh
error[E0609]: no field `3` on type `(bool, {integer}, {float})`
 --> main.rs:9:33
  |
9 |     println!("tup 3 is:{}", tup.3);
  |                                 ^ unknown field

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0609`.

数组 array

  1. 与元祖不同, 数组必须是相同类型的一组数据
  2. 与其他编程语言不同, rust 中的数组 具有固定长度
rust
fn main() {
    let arr = [1, 3, 5];
    // 多数情况下, 不需要手动指定类型, 会自动推导出类型
    // 手动指定格式: [数组类型; 数组长度]
    // let arr: [i32; 3] = [1, 3, 5];

    // 获取数组长度
    let len = arr.len();
    println!("arr len is:{}", len);

    // 通过索引访问元素
    println!("arr 0 is: {}", arr[0]);
    println!("arr 1 is: {}", arr[1]);
    println!("arr 2 is: {}", arr[2]);

    // 获取一个不存在的索引,就会报错: 索引越界
    // println!("arr 3 is: {}", arr[3]);

    // 解构取值
    let [x, y, z] = arr;
    println!("x is :{x}");
    println!("y is :{y}");
    println!("z is :{z}");
}
sh
error: this operation will panic at runtime
  --> main.rs:13:30
   |
13 |     println!("arr 3 is: {}", arr[3]);
   |                              ^^^^^^ index out of bounds: the length is 3 but the index is 3
   |
   = note: `#[deny(unconditional_panic)]` on by default

error: aborting due to 1 previous error
遍历数组
rust
fn main() {
    let arr = [1, 3, 5];

    // 最简单, 最直观的遍历
    let mut i = 0;
    while i < arr.len() {
        println!("arr[{}] is {}", i, arr[i]);
        i += 1;
    }
}
rust
fn main() {
    let arr = [1, 3, 5];

    // for in + ..操作符 遍历数组
    // 1. 0 表示范围的起始值, 即索引从 0 开始
    // 2. ..表示范围操作符, 用于创建一个范围, 不包括结尾(0..10 表示 0-9)
    // 3. arr.len() 表示数组的长度
    // 这个语法有点类似 python 的: for in range(0, len(arr))
    for i in 0..arr.len() {
        println!("arr[{}] is {}", i, arr[i]);
    }
}
rust
fn main() {
    let arr = [1, 3, 5];

    for item in arr.iter() {
        println!("item value is {}", item);
    }
}
rust
fn main() {
    let arr = [1, 3, 5];

    for item in arr.iter().enumerate() {
        let (i, x): (usize, &i32) = item;
        println!("array[{i}] = {x}");
    }
}

强制类型转换

基础类型只能小类型转大类型, 比如: u8 -> u32

rust
let a: u8 = 11;
println!("a: {}", a as u32); // 11

// 因为 bool 类型就2个值 0 和 1, 所以可以转 u8
let b: bool = false;
println!("b: {}", b as u8); // 0

数据类型解析

rust
fn main() {
    let x = 11;
    println!("x:{}", x);
    let s = x.to_string();             // 数字 -> 字符串

    println!("s:{}", s);
    let n = s.parse::<i32>().unwrap(); // 字符串 -> 数字
    println!("n:{}", n);
}

Released under the MIT License.

Layout Switch

Adjust the layout style of VitePress to adapt to different reading needs and screens.

Expand all
The sidebar and content area occupy the entire width of the screen.
Expand sidebar with adjustable values
Expand sidebar width and add a new slider for user to choose and customize their desired width of the maximum width of sidebar can go, but the content area width will remain the same.
Expand all with adjustable values
Expand sidebar width and add a new slider for user to choose and customize their desired width of the maximum width of sidebar can go, but the content area width will remain the same.
Original width
The original layout width of VitePress

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.

Spotlight

Highlight the line where the mouse is currently hovering in the content to optimize for users who may have reading and focusing difficulties.

ONOn
Turn on Spotlight.
OFFOff
Turn off Spotlight.