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) {}
相关推荐
粥里有勺糖2 分钟前
视野修炼-技术周刊第127期 | Valdi
前端·javascript·github
前端世界28 分钟前
从零搭建 ASP.NET 单文件 Web 项目:一个能真用的 BookShop 管理页实战
服务器·前端·asp.net
q***239235 分钟前
数据库操作与数据管理——Rust 与 SQLite 的集成
数据库·rust·sqlite
码上成长39 分钟前
Vue Router 3 升级 4:写法、坑点、兼容一次讲透
前端·javascript·vue.js
BBB努力学习程序设计39 分钟前
响应式页面设计与实现:让网站适配所有设备的艺术
前端·html
百锦再1 小时前
第15章 并发编程
android·java·开发语言·python·rust·django·go
IT从业者张某某1 小时前
less 工具 OpenHarmony PC适配实践
前端·microsoft·less
行走的陀螺仪2 小时前
vue3-封装权限按钮组件和自定义指令
前端·vue3·js·自定义指令·权限按钮
isyuah2 小时前
vite-plugin-openapi-ts CLI 使用指南
前端·vite
qq_398586542 小时前
浏览器中内嵌一个浏览器
前端·javascript·css·css3