📅 2020-07-23
昨天我们学习了AsRef和AsMut两个trait,使用这两个trait可以实现引用到引用的转换:
- 如果类型
U
实现了AsRef<T>
,则as_ref可以实现&U
到&T
的转换 - 如果类型
U
实现了AsMut<T>
,则as_ref可以实现从&U
到&mut T
的转换 - 如果
T
实现了AsRef<U>
,那么&T
就实现了AsRef<U>
- 如果
T
实现了AsRef<U>
,那么&mut T
就实现了AsRef<U>
- 如果
T
实现了AsMut<U>
,那么&mut T
就实现了AsMut<U>
到目前为止我们已经学习了Rust标准库中的11个常用的trait:
...📅 2020-07-22
昨天我们学习了Default trait,通过实现Default trait可以为类型提供缺省值。如果类型中的包含的其他类型都实现了Default trait,就可以通过derive宏#[derive(Default)]
来为类型自动实现Default trait,当然也可以手工实现Default trait。
...📅 2020-07-21
继续学习Rust标准库中常用的trait,在开始今天的学习之前,先把前面已经学过的trait做一个简单的复习:
- std::str::FromStr 用于字符串slice str到其他类型的转换,一个名称为Point的类型实现了FromStr trait后,调用Point::from_str()就能完成从str到Point的转换,也可以使用str.parse()隐式调用的形式。
- std::ops::Deref 用于不可变引用的解引用操作,Deref用于不可变引用的解引用操作,如
*v
。 实现Deref trait允许我们重载不可变引用的解引用运算符*
。 实现了Deref trait的智能指针可以被当做常规引用来对待,以便于访问其智能指针背后的数据。Rust为了提高在函数或方法传参时的便利性,提供了Deref强制转换(Deref coercion)功能。 - std::ops::DerefMut 用于可变引用的解引用操作,如
*v = 1;
。 实现DerefMut trait允许我们重载可变应用的解引用运算符*
。 实现了DerefMut trait的智能指针可以被当做常规可变引用来对待。因为DerefMut tait继承了Deref trait,因此也具有"Deref强制转换功能"。 - std::convert::From 如果一个类型实现了From<T>,则可以使用from实现从输入的T转换到该类型。实现From trait会自动为From<T>中的T实现Into trait。使用From trait还可以用于简化错误处理,在进行错误传播当上下游错误类型不一致时,通过实现From trait,使用
?
操作符自动实现下游到上游的错误转换。 - 类似于From和Into,std::convert::TryFrom 和 std::convert::TryInto 适用于易出错的转换场景,TryFrom, TryInto对比From和Into,多了个关联类型Error,try_from和try_into函数的返回值是Result,可以返回转换时出现的错误。
我们已经学习了FromStr, Deref, DerefMut, From, Into, TryFrom, TryInto这7个标准库中的trait,今天学习Default trait,使用Default trait可以为类型提供缺省值。
...📅 2020-07-20
昨天学习了Rust中trait的基础知识,今天开始将学习由Rust标准库中提供的经常会用到的trait。
在之前我们已经学习过了FromStr, Deref, DerefMut这3个trait,这里先做一个复习。
...📅 2020-07-19
trait类似于其他编程语言中的常被称为接口(interface)的功能,但还是有一些区别的。
trait告诉Rust编译器某个特定类型拥有可能与其他类型共享的功能。可以通过trait以一种抽象的方式定义共享的行为。可以使用trait bounds指定泛型是任何拥有特定行为的类型。
...📅 2020-07-18
今天开始学习rust中错误处理的内容。
Rust中的错误可分为 可恢复错误(recoverable) 和 不可恢复错误(unrecoverable) 两个类别。
- 可恢复错误通常代表向用户报告错误和重试操作是合理的情况,例如未找到文件
- 不可恢复错误会导致程序崩溃,例如尝试访问超过数组结尾的位置
对比其他编程语言的错误处理:
...📅 2020-07-17
前面我们学习了Box<T>
, Rc<T>
, RefCell<T>
三个智能指针。
智能指针只是一种数据结构,它们的表现类似指针,同时有额外的元数据和功能。大多数智能指针拥有其所指向数据的所有权。
Rust中的智能指针通常使用结构体实现,其区别常规结构体的显著特征在于智能指针结构体会实现Deref
trait和Drop
trait,有的智能指针结构体还会实现DerefMut
trait。
...📅 2020-07-16
昨天学习了内部可变性模式和智能指针RefCell<T>,RefCell是一个在运行时而不是在编译时执行借用规则检查的类型,如果不满足借用规则将会panic。
今天把最近一段时间学习的内容简单梳理复习一下。
Rust在解决内存管理问题时,使用了以下两个套路:
...📅 2020-07-15
昨天学习了智能指针Rc<T>
,Rc<T>
的使用场景是需要一个值有多个所有者的时候,这个场景出现在程序的运行时,Rc<T>
是带有引用计数的智能指针,可以绕开编译器对所有权的静态检查。
Rc<T>
内部使用了Box::leak
将分配的堆内存泄露以绕开编译器对所有权规则的检查,泄露出来的堆内存不再受栈内存的自动管理,而是在运行时通过对引用计数的动态检查确保在合适的时机释放堆内存。
...📅 2020-07-14
昨天学习了Rust中的智能指针Box<T>
,使用Box可以强制将数据分配在堆上,然后栈上放一个指针指向并拥有这个数据,堆内存中数据的生命周期与栈上指针的生命周期一致。
智能指针Box<T>
有三个使用场景:当有大量的数据,并且希望在确保数据不被拷贝的情况下转移所有权的时候;当有一个在编译时未知大小的类型,而又想要在需要确切大小的上下文中使用这个类型值的时候;当希望拥有一个值并只关心它的类型是否实现了特定 trait 而不是其具体类型的时候。
...