64_高级类型

1. 使用newtype模式实现类型安全和抽象

newtype模式有以下作用

  • 用来静态的保证各种值之间不会混淆并表明值的单位
  • 为类型的某些细节提供抽象能力
  • 通过轻量级的封装来隐藏内部的实现细节

2. 使用类型的别名创建类型同义词

Rust提供了类型别名的功能,为现有类型产生另外的名称(同义词),类型的别名并不是一个独立的类型,使用type关键字创建类型别名。主要用途是减少代码字符的重复。如下示例

rust 复制代码
type Kilometers = i32;

fn main() {
    let x: i32 = 5;
    let y: Kilometers = 5;
    println!("x + y = {}", x + y);
}

3. Never类型

有一个名为!的特殊类型,它没有任何值,行话称之为空类型(empty type)。我们倾向于叫never类型,因为它在不返回的函数中充当返回类型。其中,不返回值的函数也叫发散函数(diverging function)。

4. 动态大小和sized trait

rust需要在编译时确定为一个特定类型的值分配多少空间。在rust中存在动态大小的类型(Dynamically Sized Types, DST)的概念,他可以使我们在编写代码的时候使用只有在运行时才能确定大小的值。str是动态大小的类型(注意不是&str),特点是只有在运行时才能确定字符串的长度。如下列代码将无法正常工作

rust 复制代码
let s1:str = "Hello there!";
let s2:str = "How's it going?";

rust在编译的时候需要确定某个类型究竟会占多少内存,二同一类型所有的值必须使用等量的内存,所以以上代码无法正常工作。所以需要使用字符串切片(&str)来解决,因为字符串切片存储的是str的地址以及str的长度,所以过去我们在程序中存储字符串的时候都是用&str

在rust中,存储动态大小类型的数据时,总会附带一些额外的元数据来存储动态信息的大小。即使用动态大小类型的时候总会把它的值存放在某种指针后面,如字符串切片。

5. 另外一种动态大小的类型:trait

其实每一个trait都是一个动态大小的类型,可以通过名称对其引用。如为了将trait用作trait对象,必须将它放置在某种指针之后,例如&dyn TraitBox<dyn Trait>Rc<dyn trait>之后。

6. sized trait

为了处理动态大小的类型,rust提供一个Sized trait来确定类型的大小在编译时是否已知,在编译时可计算出大小的类型会自动实现这trait,rust还会为每一个泛型函数隐式的添加Sized约束。如下

rust 复制代码
fn generic<T>(t: T) {}

上面的函数会被隐式转为如下函数

rust 复制代码
fn generic<T: Sized>(t: T) {}

默认情况下,泛型函数只能被应用于编译时已经知道大小的类型,可以通过特殊语法解除这一限制,即?Sized trait约束。表示的是类型的不确定性,可能是Sized类型,可能不是Sized类型,此语法只能用在Sized上,不能用于其他trait,如下示例

rust 复制代码
fn generic<T: ?Sized>(t: &T) {}
相关推荐
ZC跨境爬虫7 小时前
跟着 MDN 学 HTML day_9:(信件语义标记)
前端·css·笔记·ui·html
前端老石人7 小时前
HTML 字符引用完全指南
开发语言·前端·html
幼儿园技术家7 小时前
前端如何设计权限系统(RBAC / ABAC)?
前端
前端摸鱼匠9 小时前
Vue 3 的v-bind合并行为:讲解v-bind与普通属性合并的规则
前端·javascript·vue.js·前端框架·ecmascript
REDcker9 小时前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
donecoding11 小时前
一个 sudo 引发的血案:npm 全局包权限错乱彻底修复
前端·node.js·前端工程化
风骏时光牛马11 小时前
Raku正则匹配与数据批量处理实操案例
前端
nbwenren11 小时前
2026实测:Gemini 3 镜像站视觉能力实践——拍照原型图,一键生成 HTML+CSS 代码
前端·css·html
Lee川11 小时前
Prisma 实战指南:像搭积木一样设计古诗词数据库
前端·数据库·后端