可以用 type
语句给已有的类型取个新的名字
别名的主要用途是避免写出冗长的模板化代码 . 如 IoResult 是 Result
类型的别名
type Str = String;
fn main() {
let s=Str::from("123");
}
方法
trait::方法( self ,...)
关联函数
<类型 as trait>::关联函数(...);
比如 官方文档 - 完全限定语法与消歧义:调用相同名称的方法
下面的trait都是 比较重要或常用的trait
并没有描述的很细节,有部分我依然处于模糊状态,未来会逐一描述细节
主要用途是 当值离开作用域时会调用drop(&mut self)
, 专业术语:析构函数
先创建的变量,最后调用drop
drop
不可以显式调用,不然就会清理2次,编译器是不会让你通过的
需要提前清理变量的话,可以使用std::mem::drop
Deref
提供了自动解引用的能力,让我们在使用智能指针的时候不需要再手动解引用了
? 运算符
转换
trait From<T> {//其他类型转换成自身类型
fn from(T) -> Self;
}
trait Into<T> {//自身类型转换成其他类型
fn into(self) -> T;
}
我们只能为自己的类型实现From
和From Into差不多,只是转换可能出错 , 当然,是否出错由你决定
trait TryFrom<T> {
type Error;
fn try_from(value: T) -> Result<Self, Self::Error>;
}
trait TryInto<T> {
type Error;
fn try_into(self) -> Result<T, Self::Error>;
}
FromStr
类型允许执行一个从&str
到Self
的可失败的转换。最常见的使用是在&str
上调用.parse()
方法
trait FromStr {
type Err;
fn from_str(s: &str) -> Result<Self, Self::Err>;
}
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
FromStr::from_str(self)
}
AsRef
被用于轻量级的引用到引用之间的转换
trait AsRef<T: ?Sized> {
fn as_ref(&self) -> &T;
}
trait AsMut<T: ?Sized> {
fn as_mut(&mut self) -> &mut T;
}
我们可以把Borrow
和BorrowMut
看作更严格的AsRef
和AsMut
trait Borrow<Borrowed: ?Sized>{//注意Borrowed是泛型
fn borrow(&self) -> &Borrowed;
}
trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> {
fn borrow_mut(&mut self) -> &mut Borrowed;
}
trait ToOwned {
type Owned: Borrow<Self>;
fn to_owned(&self) -> Self::Owned;
// 提供默认实现
fn clone_into(&self, target: &mut Self::Owned);
}
实现 迭代器 用的,你只需要实现next
方法,它就会送你一堆方法,买一送一堆
struct ABC{
A:i32
}
impl Iterator for ABC {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if self.A <3 {
self.A+=1;
Some(self.A)
}else {
None
}
}
//...一堆默认实现
}
fn main() {
let a = ABC{
A:0
};
for i in a {
println!("{}",i);// 1 2 3
}
}
官方文档 - 可重载运算符
一些上面官方文档没有trait
Trait | 符号 | 描述 |
---|---|---|
DerefMut | * | 可变解引用 |
Index | [] | 不可变索引 |
IndexMut | [] | 可变索引 |
RangeBounds | … | 区间 |
有兴趣的话自己去研究吧
Add 例子
use std::ops::Add;
struct A(i32);
struct B(i32);
impl Add<B> for A {
type Output = A;
fn add(self, rhs: B) -> Self::Output {
A(0)
}
}
impl Add<A> for B {
type Output = B;
fn add(self, rhs: A) -> Self::Output {
B(1)
}
}
fn main() {
let a=A(99);
let b=B(99);
println!("{}",(b + a).0);//1 , b+a == b.add(a)
let a=A(99);
let b=B(99);
println!("{}",(a + b).0);//0 , a+b == a.add(b)
}
类型构造默认值
过程宏(派生宏)
#[derive(Default)]
struct ABC{
a:i32
}
克隆
过程宏(派生宏)
#[derive(Clone)]
struct ABC{
a:i32
}
trait Copy:Clone{}
我们不能自己实现Copy
当一个类型实现了Copy之后,它在被移动(move)时的行为就发生了改变。默认情况下,所有的类型都有移动(move)语义 ,但是一旦某个类型实现了Copy,它就有了拷贝(copy)语义
过程宏(派生宏)
#[derive(Copy)]
struct ABC{
a:i32
}
Display
类型可以被序列化为对用户更为友好的String
类型
所有实现了Display
的类型都会自动实现ToString
:
impl<T: Display + ?Sized> ToString for T;
Debug
和Display
有着相同的签名。唯一的不同在于,只有当我门指定了{:?}
才会调用Debug
实现
过程宏(派生宏)
#[derive(Debug)]
struct ABC{
a:i32
}
实现Hash
过程宏(派生宏)
#[derive(Hash)]
struct ABC{
a:i32
}
给异常用的
trait Error: Debug + Display {//提供默认实现
fn source(&self) -> Option<&(dyn Error + 'static)>;
fn type_id(&self, _: private::Internal) -> TypeId
where
Self: 'static,
fn backtrace(&self) -> Option<&Backtrace>;
fn description(&self) -> &str;
fn cause(&self) -> Option<&dyn Error>;
}