大家好,我是砸锅。一个摸鱼八年的后端开发。熟悉 Go、Lua。第二十一天还是继续和大家一起学习 Rust😊
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情
Rust 类型系统
类型系统其实就是对类型进行定义、检查和处理的系统
多态是指在使用相同的接口时,不同类型的对象会采用不同的实现,对于静态类型系统,多态可以通过参数多态、特设多态、子类型多态来实现:
- 参数多态指的是,代码操作的类型是一个满足某些约束的参数,而非具体的类型
- 特设多态是指,同一种行为有多个不同实现的多态,一般指函数的重载
- 子类型多态是指,在运行时子类型可以被当成父类型使用
在 Rust 里,参数多态是通过泛型来实现,特设多态是通过 trait 来实现,子类型多态可以用 trait object 来实现
在定义时,Rust 不允许类型隐式转换,所以说 Rust 是强类型语言。同时在检查时,Rust 使用了静态类型系统,在编译期间保证类型正确,强类型加上静态类型,这也是 Rust 被称为类型安全的原因,代码只能按照被允许的方法和被允许的权限,访问它被授权访问的内存
在 Rust 里,对于一个作用域,最后一个表达式返回值就是作用域的返回值,如果表达式或者函数不返回任何值,则返回一个 unit(),unit 是只有一个值的类型,它的值和类型都是 ()。这个 unit() 有点像 Go 里面的 _ ,不关心值的时候可以用这个。例如 Result<(), Error>,表示只关心错误的返回内容,不关心成功的返回内容
数据类型
Rust 的原生类型包括字符、整数、浮点数、布尔值、数组、元组、切片、指针、引用、函数等
Rust 标准库支持的组合类型:
泛型数据结构
enum Option<T> {
Some(T)
None,
}
函数就是将重复代码中的参数抽取出来,使其更加通用,调用函数时,根据参数不同,得到不同的结果
泛型就是把重复数据结构中参数抽取出来,使用泛型类型时,根据不同参数,得到不同的类型
Cow(Clone-on-Write) 是 Rust 里面的数据结构,和 Option 一样,返回数据的时候,要么返回一个借用的数据(只读),要么返回一个拥有所有权的数据(可写)
在表述泛型参数的约束时,Rust 允许两种方式:
- 类似函数参数的类型声明,用” : ” 来表示约束,多个约束之间用 + 来表示
- 另一种用 where 子句,在定义的结尾来表明参数的约束
泛型函数
在声明一个函数的时候,可以不指定具体的参数或者返回值的类型,而是用泛型参数来代替:
fn in<T>(x: T) -> T {
return x;
}
fn main() {
let int = id(10);
let string = id("Try");
println!("{}, {}", int, string);
}
对于泛型函数,Rust 会进行单态化处理,也就是在编译时把所有用到的泛型函数的泛型参数展开,生成若干个函数
单态化好处是:泛型函数的调用是静态分派(static dispatch),在编译时就一一对应,保证多态的灵活性也没有任何效率的损失
缺点是:但是会导致编译速度变慢,因为一个泛型函数编译器就要找到所有用到的不同类型,一个个编译。这也导致了生成的二进制文件很大,因为泛型函数的二进制代码存在多份