欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

rust中trait的使用方法詳解

 更新時(shí)間:2023年12月25日 16:26:07   作者:王開源  
trait用中文來講就是特征,它就是一個(gè)標(biāo)記,只不過這個(gè)標(biāo)記被用在特定的地方,也就是類型參數(shù)的后面,下面我們就來學(xué)習(xí)一下trait的具體使用方法吧

介紹

trait用中文來講就是特征,它就是一個(gè)標(biāo)記,只不過這個(gè)標(biāo)記被用在特定的地方,也就是類型參數(shù)的后面,用來限定這個(gè)類型參數(shù)可能的類型范圍。trait是一種約束。

具體關(guān)系為: 變量(值空間太過寬泛,添加約束) -> 類型(約束過死,放開約束) -> 泛型(類型空間太過寬泛,添加約束) -> trait

語法上,T: TraitA意思就是對類型參數(shù)T施加TraitA這個(gè)標(biāo)記,具體實(shí)現(xiàn)為:

trait TraitA {}

struct Atype;

impl TraitA for Atype {}

對于某個(gè)類型T來說,如果它實(shí)現(xiàn)了這個(gè)TraitA,這個(gè)類型就滿足約束

fn print<T: std::fmt::Display>(p: Point<T>){...}

上面這這段代碼的意思是,Display對類型參數(shù)T做了約束,要求將來要帶入的具體類型必須實(shí)現(xiàn)Display這個(gè)trait。也就是說,trait對類型參數(shù)施加約束的同時(shí),也對具體的類型提供了能力,在Rust中約束和能力就是一體兩面,是同一個(gè)東西。

trait中包含什么

trait里面可以包含關(guān)聯(lián)函數(shù)、關(guān)聯(lián)類型和關(guān)聯(lián)常量。

關(guān)聯(lián)函數(shù)

// 下列代碼涉及所有權(quán)三態(tài)
trait Sport {
    fn play(&self) {} // 注意這里一對花括號,就是trait的關(guān)聯(lián)函數(shù)的默認(rèn)實(shí)現(xiàn)
    fn play_mut(&mut self);
    fn play_own(self);
    fn play_some() -> Self;
}

struct Football;
impl Sport for Football {
    // 由于play函數(shù)在trait中有關(guān)聯(lián)函數(shù)的默認(rèn)實(shí)現(xiàn),結(jié)構(gòu)體則可以不實(shí)現(xiàn)此函數(shù)
    fn play_mut(&mut self) {}
    fn play_own(self) {}
    fn play_some() -> Self { Self }
}

fn main() {
    let mut f = Football;
    f.play();
    f.play_mut();
    f.play_own();
    let _g = Football::play_some();
    let _g = <Football as Sport>::play_some(); // 等同于上一條代碼
}

關(guān)聯(lián)類型

在trait中,可以帶一個(gè)或多個(gè)關(guān)聯(lián)類型。關(guān)聯(lián)類型起一個(gè)類型占位功能,定義trait時(shí)聲明,在把trait實(shí)現(xiàn)到結(jié)構(gòu)體上的時(shí)候?yàn)槠渲付ň唧w的類型。

pub trait Sport {
    type ST; // 聲明關(guān)聯(lián)類型
    fn play(&self, st: Self::ST); // 將關(guān)聯(lián)類型應(yīng)用到關(guān)聯(lián)函數(shù)
}

struct Football;
pub enum SportType {
    Land,
    Water,
}

impl Sport for Football {
    type ST = SportType; // 為關(guān)聯(lián)類型指定具體類型
    fn play(&self, st: Self::ST){} // 方法中用到關(guān)聯(lián)類型
}

fn main() {
    let f = Football;
    f.play(SportType::Land);
}

在T上使用關(guān)聯(lián)類型

trait TraitA {
    type Mytype;
}

fn doit<T: TraitA>(a: T::Mytype) {} // 這里在函數(shù)中使用關(guān)聯(lián)類型

struct TypeA;
impl TraitA for TypeA {
    type Mytype = String; // 具化關(guān)聯(lián)類型為String
}

fn main() {
    doit::<TypeA>("abc".to_string()); // 指定泛型T為結(jié)構(gòu)體TypeA
}

在約束中具化關(guān)聯(lián)類型

trait TraitA {
    type Item;
}
// 意思就是限制x必須是實(shí)現(xiàn)TraitA而且它的關(guān)聯(lián)類型Item必須是String的類型
struct Foo<T: TraitA<Item=String>> {
    x: T
}

對關(guān)聯(lián)類型的約束

在定義關(guān)聯(lián)類型的時(shí)候,也可以給關(guān)聯(lián)類型添加約束。后面在具化這個(gè)類型的時(shí)候,那些類型必須要滿足于這些約束

use std::fmt::Debug;

trait TraitA {
    type Item: Debug; // 這里對關(guān)聯(lián)類型添加了Debug的約束
}

#[derive(Debug)]
struct A; // 這里在結(jié)構(gòu)體A上自動derive Debug約束

struct B;

impl TraitA for B {
    type Item = A; // 這里類型A已經(jīng)滿足Debug約束
}

在使用時(shí)可以加強(qiáng)關(guān)聯(lián)類型的約束

...
fn doit<T>(a: T)
where
    T: TriatA, // 約束T類型必須實(shí)現(xiàn)TraitA
    T::Item: Debug + PartialEq, // 同時(shí)約束trait的關(guān)聯(lián)類型必須實(shí)現(xiàn)Debug和PartialEq
{
}

關(guān)聯(lián)常量

和關(guān)聯(lián)類型不同的是,關(guān)聯(lián)常量可以在trait定義的時(shí)候指定,也可以在給具體類型實(shí)現(xiàn)的時(shí)候指定。

trait TraitA {
    const LEN: u32 = 10;
}

struct A;
impl TraitA from A {
    const LEN: u32 = 12;
}

where

當(dāng)類型參數(shù)后面有對個(gè)trait約束的時(shí)候,會顯得頭重腳輕,所以Rust提供了where語法

fn doit<T: A + B + C + D + E + F>(t: T) -> i32 {}

fn doit<T>(t: T) -> u32
where
    T: A + B + C + D + E + F
{}

約束依賴

如果某種類型要實(shí)現(xiàn)TraitA,那么它也要同時(shí)實(shí)現(xiàn)TraitB。

trait TraitB {}
trait TraitA: TraitB {}
// 等價(jià)于
trait TraitC where Self: TraitB {}

約束之間是完全平等的,沒有上下級關(guān)系

約束中同名方法的訪問

trait Shape {
    fn play(&self) {
        println!("1");
    }
}
trait Circle: Shape {
    fn play(&self) {
        println!("2");
    }
}
struct A;
impl Shape for A {}
impl Circle for A {}
impl A {
    fn play(&self) {
        println!("3");
    }
}

fn main() {
    let a = A;
    a.play(); // 調(diào)用類型A上實(shí)現(xiàn)的play方法
    <A as Circle>::play(&a); // 調(diào)用trait Circle上的play方法
    <A as Shape>::play(&a); // 調(diào)用trait Shape上的play方法
}

這種語法叫做完全限定語法,是調(diào)用類型上某個(gè)方法的完整路徑表達(dá)。

用trait實(shí)現(xiàn)能力配置

trait提供了尋找方法的范圍

  • 檢查有沒有直接在這個(gè)類型上實(shí)現(xiàn)這個(gè)方法
  • 檢查有沒有在這個(gè)類型上實(shí)現(xiàn)某個(gè)trait,trait中有這個(gè)方法 一個(gè)類型可能實(shí)現(xiàn)了多個(gè)trait,不同的trait中各有一套方法,這些不同的方法中可能還會出現(xiàn)同名方法。Rust在這里采用了一種惰性的機(jī)制,由開發(fā)者指定在當(dāng)前的mod或scope中使用哪套或哪幾套能力。因此,對應(yīng)地需要開發(fā)者手動地將要用到的trait引入當(dāng)前scope。
mod module_a {
    pub trait Shape {
        fn play(&self) {
            println!("1");
        }
    }
    pub struct A;
    impl Shape for A {}
}
mod module_b {
    use supper::module_a::Shape; // 需要同時(shí)引入A用到的trait
    use super::module_a::A;
    
    fn doit() {
        let a = A;
        a.play();
    }
}

孤兒原則

為了不導(dǎo)致混亂,Rust要求在一個(gè)模塊中,如果要對一個(gè)類型實(shí)現(xiàn)某個(gè)trait,這個(gè)類型和這個(gè)trait其中必須有一個(gè)是在當(dāng)前模塊定義的,如果必須用的話,可以用Newtyoe模式

Blanket Implementation

統(tǒng)一實(shí)現(xiàn)后,就不要對某個(gè)具體的類型再實(shí)現(xiàn)一次了,因?yàn)橥粋€(gè)trait只能實(shí)現(xiàn)一次到某個(gè)類型上。這個(gè)不像對類型做impl,可以實(shí)現(xiàn)多次(函數(shù)名要不沖突)。

trait TraitA {}
trait TraitB {}

impl<T: TraitB> TraitA for T {} // 為所有被TraitB約束的類型實(shí)現(xiàn)TraitA

impl TraitB for u32 {}
// impl TraitA for u32 {} // 無法再次實(shí)現(xiàn)

到此這篇關(guān)于rust中trait的使用方法詳解的文章就介紹到這了,更多相關(guān)rust trait內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入了解Rust的生命周期

    深入了解Rust的生命周期

    生命周期指的是引用保持有效的作用域,Rust?的每個(gè)引用都有自己的生命周期。本文將通過示例和大家詳細(xì)說說Rust的生命周期,需要的可以參考一下
    2022-11-11
  • Rust中vector的詳細(xì)用法

    Rust中vector的詳細(xì)用法

    Rust和C++同樣也有vector概念,本文主要介紹了Rust中vector的詳細(xì)用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • Rust 中解析 JSON的方法

    Rust 中解析 JSON的方法

    要開始在 Rust 中使用 JSON,您需要安裝一個(gè)可以輕松操作 JSON 的庫,目前可用的流行crate之一是 serde-json,在本文中,我們將討論如何在 Rust 中使用 JSON 解析庫,以及比較最流行的庫及其性能
    2024-03-03
  • 使用Rust實(shí)現(xiàn)日志記錄功能

    使用Rust實(shí)現(xiàn)日志記錄功能

    這篇文章主要為大家詳細(xì)介紹了使用Rust實(shí)現(xiàn)日志記錄功能的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的可以參考一下
    2024-04-04
  • 深入了解Rust中函數(shù)與閉包的使用

    深入了解Rust中函數(shù)與閉包的使用

    本文主要介紹一下Rust函數(shù)相關(guān)的內(nèi)容,首先函數(shù)我們其實(shí)一直都在用,所以函數(shù)本身沒什么可說的,我們的重點(diǎn)是與函數(shù)相關(guān)的閉包、高階函數(shù)、發(fā)散函數(shù),感興趣的可以學(xué)習(xí)一下
    2022-11-11
  • 解析Rust?struct?中的生命周期

    解析Rust?struct?中的生命周期

    rust?的生命周期保證了內(nèi)存的安全性,同時(shí)也增加了開發(fā)者的心智負(fù)擔(dān)。是在上線之前多費(fèi)心思寫代碼,還是在上線以后忙忙活活查問題,這是個(gè)?trade?off?問題,這篇文章主要介紹了Rust?struct?中的生命周期,需要的朋友可以參考下
    2022-10-10
  • Rust?所有權(quán)機(jī)制原理深入剖析

    Rust?所有權(quán)機(jī)制原理深入剖析

    這篇文章主要為大家介紹了Rust?所有權(quán)機(jī)制原理深入剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Rust文本處理快速入門

    Rust文本處理快速入門

    編程過程中有許多類型的數(shù)據(jù)要處理,其中文本處理必不可少,本文主要介紹了Rust文本處理快速入門 ,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • Rust中的Cargo構(gòu)建、運(yùn)行、調(diào)試

    Rust中的Cargo構(gòu)建、運(yùn)行、調(diào)試

    Cargo是rustup安裝后自帶的,Cargo?是?Rust?的構(gòu)建系統(tǒng)和包管理器,這篇文章主要介紹了Rust之Cargo構(gòu)建、運(yùn)行、調(diào)試,需要的朋友可以參考下
    2022-09-09
  • 為什么要使用 Rust 語言、Rust 語言有什么優(yōu)勢

    為什么要使用 Rust 語言、Rust 語言有什么優(yōu)勢

    雖然 Rust 是一種通用的多范式語言,但它的目標(biāo)是 C 和 C++占主導(dǎo)地位的系統(tǒng)編程領(lǐng)域,很多朋友會問rust語言難學(xué)嗎?rust語言可以做什么,今天帶著這些疑問通過本文詳細(xì)介紹下,感興趣的朋友一起看看吧
    2022-10-10

最新評論