首页 技术杂谈 正文
  • 本文约1998字,阅读需10分钟
  • 340
  • 0

Rust - Trait

摘要

Rust中的Trait,定义共享行为的蓝图。它们允许类型实现特定的功能契约,支持泛型编程和多态,是构建可复用、可扩展代码的基石

泛型

1、泛型:提高代码复用能力

  • 处理重复代码的问题

2、泛型是具体类型或其他属性的抽象代替

  • 你编写的代码不是最终的代码,而是一种模板,里面有一些"占位符"
  • 编译器在编译时将"占位符"替换为具体的类型
    • 例如: fn targest(list:&[T]) -> T{}
    • 里面的T都叫为类型参数:
  • 类型参数很短,通常一个字母

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子句
评论