跳至主要內容

Rust类型泛操作

LincZero大约 5 分钟

Rust类型泛操作

Rust 的数据类型

类型,我们先说一下现实中的菜系吧, 鲁菜、川菜、粤菜 、苏菜 、闽菜 、浙菜 、徽菜 、湘菜,都有不同的口味,当说到哪一个体系的菜的时候,你会知道它的特点,并且适合哪些人去吃。

那说回到计算机,数据类型也是一样的,就是存储和运算,并且要检查和保证这个数据在这个类型中是有效的。

Rust 是一个严格的静态类型语言。每个值都有唯一的数据类型,要么是整型,要么是浮点型等等。

声明变量

Rust 语言在赋值时并不强制要求指定变量的数据类型,Rust 编译器可以根据分配给它的值自动推断变量的数据类型 (类似于C++的auto,是类型推断,而非弱类型语言)

fn main(){
    // let 变量名 = 值;						// 通用格式,使用 let 关键字
    let food = "清蒸螃蟹";					// string 字符串类型
    let price = 366;						// float 类型
    let checked = true;						// boolean 类型

    println!("food is:{}", food); 			// 输出 food is:清蒸螃蟹
    println!("price is:{}", price);			// 输出 price is:366
    println!("checked is :{}", checked);	// 输出 checked is :true
}

基本数据类型

Rust 语言中有四种标量数据类型:

  • 整型
  • 浮点型
  • 布尔类型
  • 字符类型

泛类型 - 定义变量/常量

在计算机里硬件有内存条,当通电以后,会被加载到操作系统中,我们可以认为这是一个大酒店,但是它内部是要有房间的,每个房间都有自己的位置,有自己的名称,这样管理的好处是方便,直接,所以计算机也采用了这样的模式。

声明变量

let 变量名 =;           // 不指定变量类型 (本质是类型推导,而非弱类型)
let 变量名:数据类型 =;   // 指定变量类型

变量 就是给 某一块内存地址 起名字。比如: s=内存地址 1、s2=内存地址 2 。

前面说过 变量是有数据类型的,所以 内存存储的数据也是有数据类型的。

变量的命名规范

三个限制:

  • 可以包含 字母、数字 和 下划线 。

  • 变量名必须以 字母 或 下划线 开头。不能以 数字 开头。

  • 变量名是 区分大小 写的。也就是大写的 Study 和小写的 study 是两个不同的变量。

    fn main() {
        let Study = "";
        print!("{}", study)
    }
    
    // 报错如下
    print!("{}", study)
    ^^^^^ help: a local variable with a similar name exists (notice the capitalization): `Study`
    

let - 不可变变量

Rust 语言中使用 let 声明的变量,在第一次赋值之后,是不可变更不可重新赋值的,变成了 只读 状态。

  • 与其他语言不同,Rust在默认情况下变量是不可变的。对于小白来说,Rust的这种做法能大大提高了不可变类型的使用率
  • 而其他语言中,往往默认可变,而不可变需要另外标注
let price = 188;
price = 288;
print!("{}", price);

// 编译器报错提示:Cannot assign twice to immutable variable [E0384]

mut - 可变变量

Rust 语言提供了 mut 关键字表示 可变的。 在变量名的前面加上 mut 关键字告诉编译器这个变量是可以重新赋值的。

// 使用格式
let mut 变量名 =;
let mut 变量名:数据类型 =;

// 使用示例
let mut price = 188;
price = 288;
print!("{}",price);		// 输出 288

其实我觉得不写let直接用mut表示可变变量可能会更好,kotlin的 var、val、const 分别表示变量、运行期常量、编译期常量,感觉该做法比较优雅

而rust的做法是mut作为修饰关键字,复用使用来声明:let mut、static mut 静态可变变量

变量重复定义 —— 变量的隐藏

Rust 语言中允许重复定义一个相同变量名的变量。规则是 后面定义的变量会隐藏 前面定义的同名变量。

let name = "《Go语言极简一本通》";
let name = "《从0到Go语言微服务架构师》"; // 第二次定义会隐藏第一次定义的变量
println!("{}",name); 	// 输出 《从0到Go语言微服务架构师》

let price = 199;
let price = "299"; 		// 甚至对于不同类型也可以隐藏并且改变了数据类型
println!("{}",price); 	// 输出 299

@Linc:这可能会带来灵活性,但我个人认为这比较危险的操作,不如重新定义一个新名字的变量。我认为这是一个糟糕的设计

泛类型 - 常量

常量 就是那些值不能被改变的变量。定义后,再也没有任何方法可以改变常量的值。

有个特例就是 “string” 字面量。它可以不经改动就被赋给一个 static 变量,因为它 的类型标记:&’static str 就包含了所要求的生命周期 ‘static。其他的引用类型都 必须特地声明,使之拥有’static 生命周期。

const - 常量

使用 const 关键字定义常量。

常量名称的命名规则和之前变量的命名规则一样,但常量名称一般都是 大写字母

常量 可以在任意作用域里定义,包括全局作用域。也就是可以在任何地方定义。

与一些语言不同,这里的 常量 只是一个符号,会在 编译时 替换为具体的值。(编译期常量+要指定类型,所以更类似于C++的constexpr而非const或宏)

// 使用格式
const 常量名称:数据类型 =;

// 使用示例
fn main() {
    const PI:f64 = 3.1415926;
    println!("{}",PI);//输出 3.1415926
}

常量重复定义 —— 禁止

Rust 中,常量不能被隐藏,也不能被重复定义。(复习一下:变量的重复定义行为是变量的隐藏,一个操蛋设计)

const DISCOUNT:f64 = 0.8;
const DISCOUNT:f64 = 0.6;

// 编辑器报错
A value named `DISCOUNT` has already been defined in this block [E0428]

这点与大多数语言一样,也就变量的重复定义比较特殊

泛类型 - static

另一种常量的定义方式,需要注意这里的 static 前面有个 ' 符号

static BOOK: &'static str = "《Go语言极简一本通》";

可以加mut关键子使之可变