通过例子学习Rust--16.trait
Rust-系列:
特质trait
对未定义的Self定义的方法集,定义trait之后将其作用于impl块中。
对任何数据类型都可以实现trait。
派生
- 通过
#[derive]
属性,编译器提供某些trait基本实现。更复杂的行为可以手动实现所需要的trait
。
使用dyn返回trait
- Rust编译器决定了每个函数返回值需要多少空间,这意味着每个函数都必须返回一个具体类型。因此trait不能做为函数的返回值来使用,因为不同的实现造成了trait需要不同的内存量。
- 因此使用
Box
返回包含一些trait的引用更为方便,因为引用的大小是已知的,使用引用指向已分配堆中的trait,这样就能返回trait了。
- 返回指向堆的trait指针,需要使用关键字
dyn
来定义,如Box<dyn Animal>
。
运算符重载
- Rust中很多运算符通过trait来重载。
Drop
- Drop trait只有一个方法:
drop
,它会在对向离开作用域的时候自动调用该方法,它的作用是释放实现者的实例拥有的资源。 - Box,Vec,String,File,以及 Process 是一些实现了 Drop trait 来释放 资源的类型。Drop trait 也可以为任何自定义数据类型手动实现。
- 实现drop的类型可以自动销毁,你也可以手动调用drop函数将其销毁。
Iterator
- 用来对集合(数组之类)实现迭代,只需要定义返回
next
元素的方法,可以手动在impl或者自动定义。 - for结构使用
.into_iter()
方法将一些集合类型转换为迭代器。 - iter中还有很多方法,具体可以查看cargo.io查看。
impl trait
impl trait在作为返回值使用的过程之中,可以简化函数定义,前提是一定要有已经分配好堆的trait,即这个trait已经被实现了。
Clone trait
- clone trait会定义
.clone()
方法以供使用(在对于结构体等类型没有实现clone是无法使用的,结构体使用的格式是:#[derive(Clone)]
) - 相较于move方法,clone方法使用过程中能够更好的处理一些问题。
父trait
- 可以为一个trait定义它的父trait,这样,在子trait中就可以使用父trait中的方法。
记得使用dyn方法进行描述。
消除重叠trait
- 相较于之前的介绍,如果不同的trait在同一个结构体中有相同的实现方法,这样就必须使用如下的方法进行区分:
1 | trait UsernameWidget { |
Comment