Rustlings疑难记录
将做Rustlings过程中觉得疑惑或者有趣的地方单独列出来
Ownership
在./exercises/vecs/vecs1.rs
中
|
|
代码这里的第三行很明显是将a的所有权转移进了from函数中,但是结尾却可以返回为一个元组,按道理来说a在这已经没有生命周期了才对。查看rust源码如下
|
|
也就是调用了数组类型的into_vec方法。这里使用了i32类型,那么调用的就是i32的into_vec方法。到这一步我突然就有点明白为什么这个数组和vec可以共存了。与Java不同,数组本身可能不是一种完全的类型,只要数组元素类型T实现了Copy特征,传递进from的就是Copy的数组。为了验证这个想法,我写了下面这个验证函数。
|
|
果不其然,报错如下
|
|
但是实际上并不如此。array
类型只是自动实现了类型允许的特征。见array文档,摘抄如下
Arrays of any size implement the following traits if the element type allows it:
- Copy
- Clone
- Debug
- IntoIterator (implemented for [T; N], &[T; N] and &mut [T; N])
- PartialEq, PartialOrd, Eq, Ord
- Hash
- AsRef, AsMut
- Borrow, BorrowMut
这里以Copy
特征为例子探讨一下Rust的源码
|
|
空的函数体表示直接通过位复制。也就是直接把array原封不动复制过去。在Copy文档中,解释了Copy只能是bit-wise copy且不可重载。所以没办法实现类似clone的copy去防止转移所有权了。
回到最开始的问题,答案一目了然了,这里传递的数组变量并没有转移所有权,因为数组类型自动实现了i32所实现的Copy特征。
Cow(Copy on Write)
Cow是一个智能指针类型,实现了Copy on write。下面这段代码位于./exercises/standard_library_types/cow1.rs
|
|
这个问题是源于注释中 No clone occurs 这一点似乎和Copy on write的理念不符。就类似上面所有权的问题了,因为Cow
类型的From<Vec<T>>
方法实现如下
|
|
因为接受的就是所有权的转移,所以from
方法创建新值的时候直接使用了Owned
的包装。因此abs_all
处理负数的逻辑实际上是在Owned
上进行的操作,自然没有发生clone。
Macros
- 宏需要使用
#[macro_export]
宏来进行宏的暴露,可以使其全局可见。
|
|
Macros labeled with #[macro_export] are always pub and can be referred to by other crates, either by path or by #[macro_use] as described above.
也就是说,可以直接通过crate::path::macro!()
去使用,或者使用#[macro_use]
去import macros。
- 宏的匹配语句必须要以
;
分号结尾。
|
|
按照decl-marcos解释, As noted previously, macro_rules! is itself a syntax extension, meaning it is technically not part of the Rust syntax. 也就是必须要在每个匹配的rule后加分号,这是macro_rules!
自己的规则,与rust语法中模式匹配是不兼容的。具体语法参见Macros By Example
最后想说一句,Rustlings提供了from和into的traits实现题目,这实在是太聪明的决定了。能够独立完成这两个题目,就已经是具备了初步编码rust的能力了。