高级类型
类型别名
类型别名的作用:
- 减少重复
(1) 例如如下的代码(trait 对象):
Box<dyn Fn() + Send + 'static>
1 2 3 4 5 6
| let f: Box<dyn Fn() + Send + 'static> = Box::new(|| println!("hi"));
fn takes_long_type(f: Box<dyn Fn() + Send + 'static>) {
} fn returns_long_type (f: Box<dyn Fn() + Send + 'static>) {}
|
修改为别名
1 2
| type Trunk = Box<dyn Fn() + Send + 'static>; let f: Trunk = Box::new(|| println!("hi"));
|
(2) 例子2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| use std::io::Error; use std::fmt; pub trait Write { fn write(&mut self,buf :&[u8]) -> Result<usize,Error>; fn flush(&mut self) -> Result<(),Error>; fn write_all(&mut self,buf: &[u8]) -> Result<(),Error>; fn write_fmt(&mut self,fmt: fmt::Arguments) -> Result<(),Error>; }
type Result<T> = std::result::Result<T,std::io::Error>;
pub trait Write { fn write(&mut self,buf:&[u8]) -> Result<usize>; fn flush(&mut self) -> Result<()>; fn write_all(&mut self,buf: &[u8]) -> Result<()>; fn write_fmt(&mut self,fmt: Arguments) -> Result<()>; }
|
1 2 3 4 5 6 7 8 9
| type Kilometers = i32;
fn main() { let x : i32 = 5; let y: Kilometers = 6; let r: i32 = x + y;
println!("x + y = {}",r); }
|
从不返回Never type
!是一种特殊类型,被称为empty type,因为没有值
这种又叫做never type,在函数不返回的时候充当返回值
1 2 3
| fn bar() -> ! { loop{} }
|
- 例子1
猜谜游戏使用了这个参数,其中continue的值是never type
1 2 3 4
| let guess: u32 = match guess.trim().parse() { Ok(num) => num, Err(_) => continue, }
|
猜谜游戏解释链接😘
1 2 3 4 5 6 7 8 9
| impl<T> Option<T> { pub fn unwrap(self) -> T { match self { Some(val) => val, None => panic!("called 'option:;unwrap()'on a 'None' value"), } } }
|
动态大小类型和Sized trait
动态大小类型就是在运行过程中才能够知道大小的类型(dynamically sized types)DST
使用规则:
- 必须将动态大小类型的值置于某种指针之后,如Box\Rc
典型的(1)str
&str有两个值: str的地址和str的长度,大小在编译过程中可知,长度为2*usize
1 2 3 4 5 6 7
| fn main() { let s1 : &str = "Hello"; let s2 : &str = "world"; }
|
通过特征名称引用的动态大小类型
为了使用trait对象,将其放入指针之后,如&trait 或者 Box
Sized trait
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
fn generic<T>(t: T) {
}
fn generic<T: Sized>(t: T) {
}
fn generic<T: ?Sized>(t: &T) {
}
|