最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Rust指南之泛型與特性詳解

 更新時(shí)間:2022年10月08日 10:18:08   作者:微涼秋意  
泛型機(jī)制是編程語言用于表達(dá)類型抽象的機(jī)制,一般用于功能確定、數(shù)據(jù)類型待定的類,如鏈表、映射表等,這篇文章主要介紹了Rust指南泛型與特性,需要的朋友可以參考下

前言

在上篇Rust 文章中涉及到了泛型的知識(shí),那么今天就來詳細(xì)介紹一下Rust 中的泛型與特性。泛型是一個(gè)編程語言不可或缺的機(jī)制,例如在C++ 語言中用模板來實(shí)現(xiàn)泛型。泛型機(jī)制是編程語言用于表達(dá)類型抽象的機(jī)制,一般用于功能確定、數(shù)據(jù)類型待定的類,如鏈表、映射表等。

1、泛型

泛型是具體類型或其他屬性的抽象代替:

  • 所編寫的泛型代碼并非最終程序運(yùn)行的代碼,而是一種模板,含有一些"占位符"
  • 編譯器在編譯的時(shí)候?qū)?quot;占位符" 替換為具體的數(shù)據(jù)類型

優(yōu)點(diǎn):

提高代碼復(fù)用能力

  • 減少代碼重復(fù)

1.1、在函數(shù)中定義泛型

例如,定義一個(gè)對(duì)整型數(shù)字選擇排序的函數(shù):

fn max(array: &[i32]) -> i32 {
    let mut max_index = 0;
    let mut i = 1;
    while i < array.len() {
        if array[i] > array[max_index] {
            max_index = i;
        }
        i += 1;
    }
    array[max_index]
}

fn main() {
    let a = [3, 4, 6, 8, 1];
    println!("max = {}", max(&a));
}
//運(yùn)行結(jié)果:max = 8

這是一個(gè)簡(jiǎn)單的取最大值程序,可以用于處理 i32 數(shù)字類型的數(shù)據(jù),但無法用于 f64 類型的數(shù)據(jù)。

通過使用泛型我們可以使這個(gè)函數(shù)可以利用到各個(gè)類型中去:

fn max<T>(array: &[T]) -> T {
    let mut max_index = 0;
    let mut i = 1;
    while i < array.len() {
        if array[i] > array[max_index] {
            max_index = i;
        }
        i += 1;
    }
    array[max_index]
}

實(shí)際上,并不是所有的數(shù)據(jù)類型都可以比大小。當(dāng)T被自定義的結(jié)構(gòu)體或者枚舉等類型替代時(shí),這段代碼肯定就會(huì)報(bào)錯(cuò)。所以這段代碼并不是用來運(yùn)行的,而是用來描述一下函數(shù)泛型的語法格式。

1.2、結(jié)構(gòu)體中的泛型

結(jié)構(gòu)體泛型舉例:點(diǎn)坐標(biāo)結(jié)構(gòu)體,T 表示描述點(diǎn)坐標(biāo)的數(shù)據(jù)類型:

struct Point<T> {
    x: T,
    y: T
}

fn main() {
    let p1 = Point {x: 1, y: 2};
	let p2 = Point {x: 1.0, y: 2.0};
}

使用時(shí)并沒有聲明類型,這里使用的是自動(dòng)類型機(jī)制,但不允許出現(xiàn)類型不匹配的情況如下:

let p = Point {x: 1, y: 2.0};

x 與 1 綁定時(shí)就已經(jīng)將 T 設(shè)定為 i32,所以不允許再出現(xiàn) f64 的類型。如果我們想讓 x 與 y 用不同的數(shù)據(jù)類型表示,可以使用兩個(gè)泛型標(biāo)識(shí)符

struct Point<T1, T2> {
    x: T1,
    y: T2
}

1.3、枚舉類中的泛型

在枚舉類中表示泛型的方法諸如 OptionResult

enum Option<T> {
    Some(T),
    None,
}

enum Result<T, E> {
    Ok(T),
    Err(E),
}

枚舉類的具體使用可參考本專欄的文章,有較為詳細(xì)的講解。

1.4、方法中的泛型

結(jié)構(gòu)體與枚舉類都可以定義方法,那么方法也應(yīng)該實(shí)現(xiàn)泛型的機(jī)制,否則泛型的類將無法被有效的方法操作。

struct Point<T> {
    x: T,
    y: T
}

impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

fn main() {
    let p = Point { x: 2, y: 4 };
    println!("p.x = {}", p.x());
}
//運(yùn)行結(jié)果:p.x = 1

注意,impl 關(guān)鍵字的后方必須有 <T>,因?yàn)樗竺娴?T 是以之為榜樣的。

我們也可以為其中的一種泛型添加方法:

impl Point<i64> {
    fn x(&self) -> i64 {
        self.x
    }
}

impl 塊本身的泛型并沒有阻礙其內(nèi)部方法具有泛型的能力

例如:

impl<T, U> Point<T, U> {
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point {
            x: self.x,
            y: other.y,
        }
    }
}

方法 mixup 將一個(gè) Point<T, U> 點(diǎn)的 x 與 Point<V, W> 點(diǎn)的 y 融合成一個(gè)類型為 Point<T, W> 的新點(diǎn)。

2、特性

特性(trait)概念接近于 Java 中的接口(Interface),但兩者不完全相同。特性與接口相同的地方在于它們都是一種行為規(guī)范,可以用于標(biāo)識(shí)哪些類有哪些方法。

特性在 Rust 中用 trait 表示:

trait Descript {
    fn describe(&self) -> String;
}

Descript 規(guī)定了實(shí)現(xiàn)者必需有 describe(&self) -> String 方法。

例如:

struct Person {
    name: String,
    age: u16
}

impl Descript for Person {
    fn describe(&self) -> String {
        format!("{} {}", self.name, self.age)
    }
}

格式:

  • impl <特性名> for <所實(shí)現(xiàn)的類型名>

Rust 同一個(gè)類可以實(shí)現(xiàn)多個(gè)特性,每個(gè) impl 塊只能實(shí)現(xiàn)一個(gè)

2.1、默認(rèn)特性

這是特性與接口的不同點(diǎn):

  • 接口只能規(guī)范方法而不能定義方法
  • 特性可以定義方法作為默認(rèn)方法
    • 因?yàn)槭?quot;默認(rèn)",所以對(duì)象對(duì)于是否重新定義方法是自由的

舉個(gè)例子:

trait Descript {
    fn describe(&self) -> String {
        String::from("[Object]")
    }
}

struct Person {
    name: String,
    age: u8
}

impl Descript for Person {
    fn describe(&self) -> String {
        format!("{} {}", self.name, self.age)
    }
}

fn main() {
    let zhangsan = Person {
        name: String::from("kuangtu"),
        age: 28
    };
    println!("{}", zhangsan.describe());
}
//運(yùn)行結(jié)果:kuangtu 28

如果將 impl Descript for Person 塊中的內(nèi)容去掉,那么運(yùn)行結(jié)果就是 [Object]

2.2、特性做參數(shù)

很多情況下我們需要傳遞一個(gè)函數(shù)做參數(shù),例如回調(diào)函數(shù)、設(shè)置按鈕事件等。在 Java 中函數(shù)必須以接口實(shí)現(xiàn)的類實(shí)例來傳遞,在 Rust 中可以通過傳遞特性參數(shù)來實(shí)現(xiàn):

fn output(object: impl Descript) {
    println!("{}", object.describe());
}

任何實(shí)現(xiàn)了 Descript 特性的對(duì)象都可以作為這個(gè)函數(shù)的參數(shù),這個(gè)函數(shù)沒必要知道傳入對(duì)象有沒有其他屬性或方法,只需要了解它一定有 Descript 特性規(guī)范的方法就可以了。當(dāng)然,此函數(shù)內(nèi)也無法使用其他的屬性與方法。

特性參數(shù)還可以用這種等效語法實(shí)現(xiàn):

fn output<T: Descriptive>(object: T) {
    println!("{}", object.describe());
}

這是一種風(fēng)格類似泛型的語法糖,這種語法糖在有多個(gè)參數(shù)類型均是特性的情況下十分實(shí)用:

fn output_two<T: Descriptive>(arg1: T, arg2: T) {
    println!("{}", arg1.describe());
    println!("{}", arg2.describe());
}

特性作類型表示時(shí)如果涉及多個(gè)特性,可以用 + 符號(hào)表示,例如:

fn notify(item: impl Summary + Display)
fn notify<T: Summary + Display>(item: T)

注意:僅用于表示類型的時(shí)候,并不可以在 impl 塊中使用。

復(fù)雜的實(shí)現(xiàn)關(guān)系可以使用 where 關(guān)鍵字簡(jiǎn)化,例如:

fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U)

可以簡(jiǎn)化為:

fn some_function<T, U>(t: T, u: U) -> i32
    where T: Display + Clone,
          U: Clone + Debug

泛型通過與特性的結(jié)合可以實(shí)現(xiàn)上面任意類型值比較的案例:

trait Comparable {
    fn compare(&self, object: &Self) -> i8;
}

fn max<T: Comparable>(array: &[T]) -> &T {
    let mut max_index = 0;
    let mut i = 1;
    while i < array.len() {
        if array[i].compare(&array[max_index]) > 0 {
            max_index = i;
        }
        i += 1;
    }
    &array[max_index]
}

impl Comparable for f64 {
    fn compare(&self, object: &f64) -> i8 {
        if &self > &object { 1 }
        else if &self == &object { 0 }
        else { -1 }
    }
}

fn main() {
    let arr = [1.0, 3.0, 7.0, 4.0, 2.0];
    println!("maximum of arr is {}", max(&arr));
}
//運(yùn)行結(jié)果:maximum of arr is 7

Tip: 由于需要聲明 compare 函數(shù)的第二參數(shù)必須與實(shí)現(xiàn)該特性的類型相同,所以 Self (注意大小寫)關(guān)鍵字就代表了當(dāng)前類型(不是實(shí)例)本身。

2.3、特性做返回值

格式如下:

fn person() -> impl Descript {
    Person {
        name: String::from("Cali"),
        age: 24
    }
}

注意:特性做返回值只接受實(shí)現(xiàn)了該特性的對(duì)象做返回值且在同一個(gè)函數(shù)中所有可能的返回值類型必須完全一樣。

比如結(jié)構(gòu)體 A 與結(jié)構(gòu)體 B 都實(shí)現(xiàn)了特性 Trait,下面這個(gè)函數(shù)就是錯(cuò)誤的:

fn some_function(bool bl) -> impl Descriptive {
    if bl {
        return A {};
    } else {
        return B {};
    }
}

到此這篇關(guān)于Rust指南泛型與特性的文章就介紹到這了,更多相關(guān)Rust泛型與特性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Rust個(gè)人學(xué)習(xí)小結(jié)之Rust的循環(huán)

    Rust個(gè)人學(xué)習(xí)小結(jié)之Rust的循環(huán)

    這篇文章主要介紹了Rust個(gè)人學(xué)習(xí)小結(jié)之Rust的循環(huán),今天主要了解了Rust語言的3種循環(huán)方法:?loop、while、for,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 解析Rust?struct?中的生命周期

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

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

    Rust生成隨機(jī)數(shù)的項(xiàng)目實(shí)踐

    Rust標(biāo)準(zhǔn)庫中并沒有隨機(jī)數(shù)生成器,常見的解決方案是使用rand包,本文主要介紹了Rust生成隨機(jī)數(shù)的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Windows系統(tǒng)下安裝Rust環(huán)境超詳細(xì)教程

    Windows系統(tǒng)下安裝Rust環(huán)境超詳細(xì)教程

    這篇文章主要介紹了如何在Windows系統(tǒng)上安裝mingw64和Rust,mingw64是一個(gè)輕便的C語言編譯環(huán)境,可以替代Rust默認(rèn)使用的Visual?Studio,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2025-02-02
  • Rust 中的閉包之捕獲環(huán)境的匿名函數(shù)

    Rust 中的閉包之捕獲環(huán)境的匿名函數(shù)

    這篇文章介紹了Rust編程語言中的閉包,包括閉包的定義、使用、捕獲環(huán)境中的變量、類型推斷與注解、與函數(shù)的比較以及實(shí)際應(yīng)用,閉包具有捕獲環(huán)境、類型推斷和高效性等特性,是Rust中一個(gè)非常強(qiáng)大的工具,感興趣的朋友一起看看吧
    2025-02-02
  • rust 如何使用 cargo-nextest 替代 cargo test

    rust 如何使用 cargo-nextest 替代 cargo te

    cargo-nextest 是新一代的rust測(cè)試程序,能夠極大提升測(cè)試性能,可以完全替代 cargo test 命令,這篇文章主要介紹了rust 如何使用 cargo-nextest 替代 cargo test,需要的朋友可以參考下
    2024-05-05
  • Rust常用功能實(shí)例代碼匯總

    Rust常用功能實(shí)例代碼匯總

    通過一系列實(shí)用示例展示了Rust在文件操作、網(wǎng)絡(luò)請(qǐng)求、并發(fā)編程、命令行工具以及數(shù)據(jù)庫操作等方面的應(yīng)用,這些示例不僅展示了 Rust 的強(qiáng)大功能,還提供了實(shí)際開發(fā)中的指導(dǎo)和參考,通過這些示例,您可以更好地理解 Rust 的特性,并將其應(yīng)用于您的項(xiàng)目中
    2024-12-12
  • Rust語言開發(fā)環(huán)境搭建詳細(xì)教程(圖文教程)

    Rust語言開發(fā)環(huán)境搭建詳細(xì)教程(圖文教程)

    本文主要介紹了rust編程語言在windows上開發(fā)環(huán)境的搭建方法,文中通過圖文的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • Rust中使用Serde對(duì)json數(shù)據(jù)進(jìn)行反序列化

    Rust中使用Serde對(duì)json數(shù)據(jù)進(jìn)行反序列化

    JSON作為目前流行的數(shù)據(jù)格式之一,被大家廣泛使用,在日常的開發(fā)實(shí)踐中,將JSON數(shù)據(jù)反序列化為對(duì)應(yīng)的類型具有重要的意義,在Rust中,Serde幾乎成了JSON數(shù)據(jù)解析的事實(shí)標(biāo)準(zhǔn),本文將給大家介紹Rust中使用Serde對(duì)json數(shù)據(jù)進(jìn)行反序列化,需要的朋友可以參考下
    2024-01-01
  • Rust動(dòng)態(tài)調(diào)用字符串定義的Rhai函數(shù)方式

    Rust動(dòng)態(tài)調(diào)用字符串定義的Rhai函數(shù)方式

    Rust中使用Rhai動(dòng)態(tài)調(diào)用字符串定義的函數(shù),通過eval_expression_with_scope實(shí)現(xiàn),但參數(shù)傳遞和函數(shù)名處理有局限性,使用FnCall功能更健壯,但更復(fù)雜,總結(jié)提供了更通用的方法,但需要處理更多錯(cuò)誤情況
    2025-02-02

最新評(píng)論

临洮县| 寿宁县| 辽宁省| 琼海市| 博白县| 巴彦县| 罗定市| 蓝田县| 吉水县| 新安县| 临武县| 巴马| 灌云县| 驻马店市| 萨嘎县| 定南县| 灵璧县| 常德市| 长葛市| 和林格尔县| 平舆县| 松阳县| 英超| 宜川县| 祥云县| 慈溪市| 舒城县| 福海县| 姜堰市| 南溪县| 迁安市| 长岛县| 瑞安市| 湛江市| 定日县| 米泉市| 桦甸市| 蕉岭县| 宁远县| 天长市| 将乐县|