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) {}
相关推荐
鹏多多几秒前
Vue3响应式原理Proxy的深度剖析
前端·javascript·vue.js
不可能的是1 分钟前
深度解析:Sass-loader Legacy API 警告的前世今生与完美解决方案
前端·javascript
情绪的稳定剂_精神的锚1 分钟前
VSCODE开发一个代码规范的插件入门
前端
养老不躺平5 分钟前
关于nest项目打包
前端·javascript
Python私教23 分钟前
源滚滚Rust全栈班v1.02 无符号整数详解
开发语言·后端·rust
Mike_jia1 小时前
uuWAF:开源Web应用防火墙新标杆——从工业级防护到智能防御实战解析
前端
掘金安东尼1 小时前
Chrome 17 岁了——我们的浏览器简史
前端·javascript·github
袁煦丞1 小时前
群晖NAS FTP远程文件仓库全球访问:cpolar内网穿透实验室第524个成功挑战
前端·程序员·远程工作
前端小巷子1 小时前
JS 打造动态表格
前端·javascript·面试
excel1 小时前
从卷积到全连接:用示例理解 CNN 的分层
前端