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) {}
相关推荐
熊猫钓鱼>_>5 分钟前
基于MCP的桥梁设计规范智能解析与校审系统构建实践
前端·easyui·设计规范
若初&16 分钟前
文件上传Ⅲ
前端·web安全
若愚679217 分钟前
前端取经路——前端安全:构建坚不可摧的Web应用防线
前端·安全
邪恶的贝利亚20 分钟前
定时器设计
java·linux·前端
inksci41 分钟前
Vue 3 打开 el-dialog 时使 el-input 获取焦点
前端·javascript·vue.js
若愚67921 小时前
前端取经路——量子UI:响应式交互新范式
前端·ui·交互
PHASELESS4112 小时前
HTML常用标签用法全解析:构建语义化网页的核心指南
前端·html
粉末的沉淀2 小时前
css:倒影倾斜效果
前端·css
zandy10112 小时前
如何快速入门-衡石科技分析平台
服务器·前端·科技·数据库管理员