Rust - Trait
泛型
1、泛型:提高代码复用能力
- 处理重复代码的问题
2、泛型是具体类型或其他属性的抽象代替
- 你编写的代码不是最终的代码,而是一种模板,里面有一些"占位符"
- 编译器在编译时将"占位符"替换为具体的类型
- 例如: fn targest
(list:&[T]) -> T{} - 里面的T都叫为类型参数:
- 例如: fn targest
- 类型参数很短,通常一个字母
1、函数定义中的泛型
// 函数中泛型
fn get_list<T>(list:&[T]) -> T{
let mut largest = list[0];
for &item in list{
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let number = [1,23,4,5,6,323,232];
let result = get_list(&number);
}
2、Struct中定义泛型
struct Point<T>{
x:T,
y:T,
}
3、方法定义中的泛型
1、为struct或enum实现方法的时候,可在定义中使用泛型
struct Point<T>{
x:T,
y:T,
}
// 方法中定义泛型
impl<T> Point<T> {
fn x(&self) ->&T {
&self.x
}
}
4、trait
1、trait会告诉Rust编译器
- 某种类型具有哪些并且可以与其他类型共享的功能
2、trait:抽象的定义共享功能
3、trait约束:泛型类型参数指定为实现了特定行为的类型
5、定义一个Trait
1、trait的定义:把方法签名放一起,从而来定义实现某种目的所必需的一组行为
- 关键字:trait
2、只定义方法签名,不提供具体实现
3、可以定义多个方法,每个方法后面使用;
4、实现了该Trait就必须把里面的方法实现
5.1、练习
// 代码:main.rs
use trait_test::{NewsArticle, Summary};
fn main() {
//let number = [1,23,4,5,6,323,232];
//let result = get_list(&number);
let s = NewsArticle{
headline:String::from("a"),
location:String::from("b"),
author:String::from("c"),
content:String::from("d"),
};
println!("{}",s.summarize());
}
// 代码:lib.rs
// 实现一个trait
pub trait Summary {
fn summarize(&self) -> String;
}
// 定义结构体
pub struct NewsArticle{
pub headline:String,
pub location:String,
pub author:String,
pub content:String,
}
// 实现这个trait
impl Summary for NewsArticle {
fn summarize(&self) -> String{
format!("{},{},{}",self.headline,self.location,self.author)
}
}
6、实现trait的约束
1、可以在某个类型上实现某个trait的前提条件是:
- 这个类型或这个trait是在本地crate里定义的
2、无法为外部类型来实现外部的trait:
- 这个限制是程序属性的一部分(也就是一致性)
- 更具体地说是孤儿规则:之所以这样命名是因为父类型不存在
7、默认实现
1、可以在trait中直接实现了方法,
2、重写:后面调用者不想用默认实现,可以重写该方法
pub trait Summary {
fn summarize(&self) -> String{
String::from("默认实现")
}
}
3、默认实现的Trait可以调用Trait的其他方法,即使这个方法没有实现
pub trait Summary {
fn summarize(&self) -> String{
format!("(调用trait中的get_string方法{})",self.get_string())
}
fn get_string(&self) -> String;
}
// 定义结构体
pub struct NewsArticle{
pub headline:String,
pub location:String,
pub author:String,
pub content:String,
}
// 实现这个trait
impl Summary for NewsArticle {
fn get_string(&self) -> String{
format!("@{}",self.author)
}
}
8、Trait作为参数
1、impl Trait语法:适用于简单情况
2、Trait bound 语法: 可用于复杂情况
- impl trait 语法是trait bound的语法糖
3、使用+ 指定多个Trait bound
4、Trait bound 使用where子句
- 在方法签名后指定where子句
推荐阅读: