入坑第一天 - 基础概念

113 阅读5分钟

入坑第一天

基础概念

每一个Rust程序都会用到的基础知识:变量、基本类型、函数、注释和控制流.

一、变量与常量

变量和可变性

变量默认是不可改变的

当变量不可改变时,一旦值被绑定一个名称上,就不能改变这个值 文件名:src/main.rs

fn main() {
    let x = 5;
    println!("The value of x is: {x}");
    x = 6;
    println!("The value of x is: {x}");
}

可变性也是非常有用的,可以用来更方便地编写代码。尽管变量默认是不可变的,你仍然可以在变量名前添加 mut 来使其可变。

fn main() {
    let mut x = 5;
    println!("The value of x is: {x}");
    x = 6;
    println!("The value of x is: {x}");
}

常量

类似不可变变量,常量 是绑定到一个名称的不允许改变的值。且不允许对常量使用常量,声明常量使用const关键字而不是let,并且必须注明值的类型。

常量只能被设置为常量表达式,而不可以是其他任何只能在运行时计算出的值。

Rust 对常量的命名约定是在单词之间使用全大写加下划线。 栗子:

const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

隐藏

我们可以定义一个与之前变量同名的新变量。此时第一个变量就被第二个变量隐藏(shadowing)了。此时调用或者使用编译器只看到第二个变量。直到第二个变量也被隐藏或者它所属的作用域结束。

fn main() { 
    let x = 5; 
    let x = x + 1; 
{ 
    let x = x * 2; 
    println!("The value of x in the inner scope is: {x}"); 
} 
println!("The value of x is: {x}"); }

输出:

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 0.31s
     Running `target/debug/variables`
The value of x in the inner scope is: 12
The value of x is: 6

mut隐藏的区别,当尝试对变量重新赋值时,若没有使用let关键字,就会导致编译时错误。

mut 与隐藏的另一个区别是,当再次使用 let 时,实际上创建了一个新变量,我们可以改变值的类型,并且复用这个名字。

二、数据类型

Rust是静态类型语言。必须在编译时知道所有变量的类型。

数据类型子集:标量复合

标量类型

标量类型代表一个单独的值。Rust有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。

整型

整数 是一个没有小数部分的数字。我们在第二章使用过 u32 整数类型。该类型声明表明,它关联的值应该是一个占据 32 比特位的无符号整数(有符号整数类型以 i 开头而不是 u)。下面表格展示了 Rust 内建的整数类型。我们可以使用其中的任一个来声明一个整数值的类型。有符号 和 无符号 代表数字能否为负值。

长度有符号无符号
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
archisizeusize

u8可以存放0到255的值,如果修改为256会发生整型溢出的问题。

浮点型

Rust 也有两个原生的 浮点数floating-point numbers)类型,它们是带小数点的数字。Rust 的浮点数类型是 f32 和 f64,分别占 32 位和 64 位。默认类型是 f64。所有的浮点型都是有符号的。 f32 是单精度浮点数,f64 是双精度浮点数。

fn main() {
    let x = 2.0; // f64
    let y: f32 = 3.0; // f32
}
布尔值

Rust 中的布尔类型有两个可能的值:true 和 false。Rust 中的布尔类型使用 bool 表示

fn main() {
    let t = true;
    let f: bool = false; // with explicit type annotation
}
字符类型

Rust 的 char 类型是语言中最原生的字母类型。

我们用单引号声明 char 字面量,而与之相反的是,使用双引号声明字符串字面量。

Rust 的 char 类型的大小为四个字节

fn main() {
    let c = 'z';
    let z: char = 'ℤ'; // with explicit type annotation
    let heart_eyed_cat = '😻';
}

复合类型

复合类型Compound types)可以将多个值组合成一个类型。Rust 有两个原生的复合类型:元组(tuple)和数组(array)。

元组类型

元组是一个将多个其他类型的值组合进一个复合类型的主要方式。

元组类型特点

  • 长度固定,一旦声明,其长度不会增大或缩小
  • 使用包含在圆括号中的逗号分隔的值列表来创建一个元组。元组中的每一个位置都有一个类型,而且这些不同值的类型也不必是相同的。
fn main() {
    let tup: (i32, f64, u8) = (500, 6.4, 1);
}

使用方式

  • 模式匹配: 使用点号(.)后跟值的索引来直接访问它们。元组的第一个索引值是0,一次累加
  • 解构

结构

fn main() {
    let tup = (500, 6.4, 1);
    let (x, y, z) = tup;
    println!("The value of y is: {y}");
}

模式匹配

fn main() {
    let x: (i32, f64, u8) = (500, 6.4, 1);
    let five_hundred = x.0;
    let six_point_four = x.1;
    let one = x.2;
}

不带任何值的元组有个特殊的名称,叫做 单元(unit)  元组。这种值以及对应的类型都写作 (),表示空值或空的返回类型。如果表达式不返回任何其他值,则会隐式返回单元值。

数组类型

数组与元组不同,数组中的每个元素的类型必须相同。且数组长度固定。

定义:在方括号中包含每个元素的类型,后跟分号,再后跟数组元素的数量

访问:数组是可以在栈 (stack) 上分配的已知固定大小的单个内存块。可以使用索引来访问数组的元素。超过索引值是无效访问。

fn main() {
    let a = [1, 2, 3, 4, 5];
    let b: [i32; 5] = [1, 2, 3, 4, 5]; // 表示 i32是每个元素的类型,数字5表hi是包含5个元素。
    let c = [3; 5]; // 表示元素的值等于3,且5个元素的值都是3.
}

函数