Open zoniony opened 4 years ago
这本书很不错 抄书笔记
panic!("This function never returns!")
st:: process::exit
parse::<i32>()
接口中可以定义方法,并支持默认实现
接口中不能实现另一个接口,但是接口之间可以继承。
同一个接口可以同时被多个类型实现,但不能被同一个类型实现多次
使用impl关键字为类型实现接口方法
使用trait关键字来定义接口
为不同的类型实现 trait,属于一种函数重载,也可以说函数重载就是一种 Ad-hoc多态
这是因为Rust遵循一条重要的规则:孤儿规则(Orphan Rule)。
孤儿规则规定,如果要实现某个trait,那么该trait和要实现该trait的那个类型至少有一个要在当前crate中定义。
Rust不支持传统面向对象的继承,但是支持trait继承。
const
static
&T as *const T
&mut T as *mut T
drop-flag
dropflag
RefCell<T>
struct A { a: u32, b: Box<u64>, }
struct B(i32, f64, char); struct N;
enum E { H(32), M(Box<u32>), }
Rust 也引入了新的语义:复制(Copy)语义和移动(Move)语义。复制语 义对应值语义,移动语义对应引用语义。这样划分是因为引入了所有权 机制,在所有权机制下同时保证内存安全和性能。
一个值的所有权被转移给另外一个变量绑定的过程,就叫作所有权转移。
Rust中分配的每块内存都有其所有者,所有者负责该内存的释放和读写权限,并且每次每个值只能有唯一的所有者。这就是 Rust的所有权机制 (OwnerShip)。 所有权的类型系统理论
Rust的所有权在类型系统理论中称为仿射类型(affine type),它 属于类型理论中子结构类型系统( Substructural Type System)的概念
子结构类型系统又是子结构逻辑(Substructural Logic)在类型系统中的应用
而子结构逻辑属于证明理论里的推理规则,其规则包含如 下几点。
所有权的特点 所有者拥有以下三种权限
控制资源(不仅仅是内存)的释放
出借所有权,包括不可变(共享)的和可变(独占)的。
转移所有权。
在进行赋值操作时,作为右值的变量 会默认执行移动语义来转移所有权,从而保证了内存安全
对于复合类型来说,是复制还是移动,取决于其成员的类型,但是Rust并不会默 认为其实现Copy
枚举体和结构体是类似的,当成员均为复制语义类型时,不会自动 实现Copy。
对于元组类型来说,其本身实现了Copy,如果元素均为 复制语义类型,则默认是按位复制的,否则会执行移动语义
数组和Option类型与元组类型都遵循这样的规则:如果元素都是复制语义类型,也就是都实现了Copy,那么它们就可以按位复制,否则就 转移所有权
let a = b
是函数参数签名也支 持模式匹配,相当于使用 let 将 v 重新声明成了可变绑定。
使用可变借用的前提是,出借所有权的绑定变量必须是一个 可变绑定
引用(Reference)是 Rust 提供的一种指针语义
用是基于指针 的实现,它与指针的区别是,指针保存的是其指向内存的地址,而引用 可以看作某块内存的别名(Alias),使用它需要满足编译器的各种安 全检查规则
在所有权系统中,引用&x也可称为x的借用(Borrowing),通过 &操作符来完成所有权租借
借用所有权会让所有者(owner)受到如 下限制:
引用在离开作用域之时,就是其归还所有权之时。
为了保证内存安全,借用必须遵循以下三个规则
规则一是为了防止出现悬垂指针。规则二和三可以总结为一条核心 的原则:共享不可变,可变不共享
不可变借用可以被出借多次,因为它不能修改内存数据,因此它也 被称为共享借用(引用),可变借用只能出借一次,否则,难以预料数 据何时何地会被修改。
Rust的借用检查带来了如下好处:
解引用操作会获得所有权
fn print(s: &str); // 省略 fn print<'a>(s: &'a str); // 展开 fn debug(lvl: uint, s: &str); // 省略 fn debug<'a>(lvl: uint, s: &'a str); // 展开 fn substr(s: &str, until: uint) -> &str; // 省略 fn substr<'a>(s: &'a str, until: uint) -> &'a str; // 展开 fn get_str() -> &str; // 非法 fn frob(s: &str, t: &str) -> &str; // 非法 fn get_mut(&mut self) -> &mut T; // 省略 fn get_mut<'a>(&'a mut self) -> &'a mut T; // 展开 /// // 省略 fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command /// // 展开 fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command fn new(buf: &mut [u8]) -> BufWriter; // 省略 fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // 展开
T:'a
'a
T:Trait+'a
TODO
r#
震惊
Σ(っ °Д °;)っ 草 被作者大大发现了
加油
这本书很不错 抄书笔记
3.类型系统
3.1 通用概念
3.1.1类型系统的作用
3.1.2 类型系统的分类
3.1.3 类型系统与多态性
3.2 Rust类型系统概述
3.2.1 类型大小
panic!("This function never returns!")
,或者用于退出函数的st:: process::exit
,这类函数永远都不会有返回值3.2.2 类型推导
parse::<i32>()
这样的形式为泛型函数标注类型3.3泛型
3.3.1 泛型函数
3.3.2 泛型返回值自动推导
3.4 深入trait
3.4.1 接口抽象
接口中可以定义方法,并支持默认实现
接口中不能实现另一个接口,但是接口之间可以继承。
同一个接口可以同时被多个类型实现,但不能被同一个类型实现多次
使用impl关键字为类型实现接口方法
使用trait关键字来定义接口
为不同的类型实现 trait,属于一种函数重载,也可以说函数重载就是一种 Ad-hoc多态
这是因为Rust遵循一条重要的规则:孤儿规则(Orphan Rule)。
孤儿规则规定,如果要实现某个trait,那么该trait和要实现该trait的那个类型至少有一个要在当前crate中定义。
Rust不支持传统面向对象的继承,但是支持trait继承。
3.4.2 泛型约束
3.4.3 抽象类型
3.5 类型转换
3.5.1 Deref解引用
3.5.2 as操作符
3.5.3 from和into
4. 内存管理
4.1 通用概念
4.2 Rust资源管理
4.2.1 变量和函数
const
关键字定义,并且需要显式指明类型,只能进行简单赋值,只能使用支持CTFE的表达式static
关键字定义,跟常量一样需要显式指明类型, 进行简单赋值,而不能使用任何表达式4.2.2 智能指针与RALL
&T as *const T
和&mut T as *mut T
drop-flag
的“魔法”,在函数调用栈中为离开作用域的变量自动插入布尔标记,标 注是否调用析构函数dropflag
drop-flag
4.2.3 内存泄漏与内存安全
RefCell<T>
,它提供了一种内部可变性,这意味着,它对编译器来说是不可变的,但在运行过程中,包含在其中的内部数据是 可变的4.2.4 复合类型的内存分配和布局
5.所有权系统
5.1 通用概念
5.2 所有权机制
Rust 也引入了新的语义:复制(Copy)语义和移动(Move)语义。复制语 义对应值语义,移动语义对应引用语义。这样划分是因为引入了所有权 机制,在所有权机制下同时保证内存安全和性能。
一个值的所有权被转移给另外一个变量绑定的过程,就叫作所有权转移。
Rust中分配的每块内存都有其所有者,所有者负责该内存的释放和读写权限,并且每次每个值只能有唯一的所有者。这就是 Rust的所有权机制 (OwnerShip)。 所有权的类型系统理论
Rust的所有权在类型系统理论中称为仿射类型(affine type),它 属于类型理论中子结构类型系统( Substructural Type System)的概念
子结构类型系统又是子结构逻辑(Substructural Logic)在类型系统中的应用
而子结构逻辑属于证明理论里的推理规则,其规则包含如 下几点。
所有权的特点 所有者拥有以下三种权限
控制资源(不仅仅是内存)的释放
出借所有权,包括不可变(共享)的和可变(独占)的。
转移所有权。
在进行赋值操作时,作为右值的变量 会默认执行移动语义来转移所有权,从而保证了内存安全
对于复合类型来说,是复制还是移动,取决于其成员的类型,但是Rust并不会默 认为其实现Copy
枚举体和结构体是类似的,当成员均为复制语义类型时,不会自动 实现Copy。
对于元组类型来说,其本身实现了Copy,如果元素均为 复制语义类型,则默认是按位复制的,否则会执行移动语义
数组和Option类型与元组类型都遵循这样的规则:如果元素都是复制语义类型,也就是都实现了Copy,那么它们就可以按位复制,否则就 转移所有权
5.3 绑定、作用域和生命周期
let a = b
因为a是String类型,不能实现 Copy,所以这种行为其实也可以理解为对a进行解绑,然后重新绑定给 b。5.3.1 不可变与可变
5.3.2 绑定的时间属性 生命周期
5.4 所有权借用
是函数参数签名也支 持模式匹配,相当于使用 let 将 v 重新声明成了可变绑定。
使用可变借用的前提是,出借所有权的绑定变量必须是一个 可变绑定
引用(Reference)是 Rust 提供的一种指针语义
用是基于指针 的实现,它与指针的区别是,指针保存的是其指向内存的地址,而引用 可以看作某块内存的别名(Alias),使用它需要满足编译器的各种安 全检查规则
在所有权系统中,引用&x也可称为x的借用(Borrowing),通过 &操作符来完成所有权租借
借用所有权会让所有者(owner)受到如 下限制:
引用在离开作用域之时,就是其归还所有权之时。
为了保证内存安全,借用必须遵循以下三个规则
规则一是为了防止出现悬垂指针。规则二和三可以总结为一条核心 的原则:共享不可变,可变不共享
不可变借用可以被出借多次,因为它不能修改内存数据,因此它也 被称为共享借用(引用),可变借用只能出借一次,否则,难以预料数 据何时何地会被修改。
Rust的借用检查带来了如下好处:
解引用操作会获得所有权
5.5 生命周期参数
5.5.1 显示生命周期参数
5.5.2 省略生命周期参数
5.5.3 生命周期限定
T:'a
表示T类型中的任何引用都要“活得”和'a
一样长。T:Trait+'a
,表示T类型必须实现Trait这个trait,并且T类型中 任何引用都要“活得”和'a一样长5.5.4 trait对象的生命周期
TODO
6 函数,闭包和迭代器
6.1 函数
r#
作为前缀,即可使用关键字为函数命名,该语法一般用于 FFI中6.1.1 函数屏蔽
6.1.2 函数参数的匹配模式
6.1.3函数返回值
6.1.4 泛型函数