国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)

這篇具有很好參考價值的文章主要介紹了研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

高級trait

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

我們使用type關(guān)鍵字即可聲明一個關(guān)聯(lián)類型,關(guān)聯(lián)類型的作用就是簡化和隱藏顯示類型(個人認(rèn)為)

  • 簡化:一個很長的類型總是被需要時,需要開發(fā)者耗費精力的重復(fù)書寫,而且若有改動,則需要改多個地方
  • 隱藏:對外部調(diào)用者隱藏,外部調(diào)用者無需知道它指的是什么,只要可快速使用即可
trait test {
    type Res = Result<i32, Box<&'static str>>;
    fn test_res() -> Res{
        //...
    }
}

為什么不用泛型而是Type

使用泛型,我們就需要在每次使用實現(xiàn)時顯示的標(biāo)注類型,但是當(dāng)針對一個多處使用且無需修改類型的場景時,無疑耗時耗力,換而言之,Type犧牲部分靈活度換取常用性

運(yùn)算符重載(重要等級不高)

Rust 并不允許創(chuàng)建自定義運(yùn)算符或重載任意運(yùn)算符,不過 std::ops 中所列出的運(yùn)算符和相應(yīng)的 trait 可以通過實現(xiàn)運(yùn)算符相關(guān) trait 來重載
因此我們就可以重載例如+,/,-,*等,
以下是官方給出的例子:

use std::ops::Add;

#[derive(Debug, Copy, Clone, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Output = Point;

    fn add(self, other: Point) -> Point {
        Point {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

fn main() {
    assert_eq!(
        Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
        Point { x: 3, y: 3 }
    );
}

重名方法消除歧義

當(dāng)我們實現(xiàn)多個trait的時候,若遇到多個trait有同樣的方法名,那么就會產(chǎn)生重名歧義,此時最晚實現(xiàn)的會覆蓋前面的,為了消除歧義,我們可以采用trait::fn(&type)來申明調(diào)用

struct a {}

trait b {
    fn get(&self) {}
}

trait c {
    fn get(&self) {}
}

impl b for a {
    fn get(&self) {
        todo!()
    }
}

impl c for a {
    fn get(&self) {
        todo!()
    }
}

fn main() {
    let a_struct = a {};

    b::get(&a_struct);
    c::get(&a_struct);
}

never type

Rust 有一個叫做 ! 的特殊類型,我們稱作never type因為他表示函數(shù)從不返回的時候充當(dāng)返回值

fn no_feedback()->!{
	//...
}

continue 的值是 !

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

返回閉包

一個函數(shù)的返回值是可以為一個閉包的,這個沒有限制,具體來說我們簡單了解寫法即可

fn test()->Box<dyn Fn()>{
	//...
}

我們通過返回一個Box即將返回值寫入堆中
例如:

fn returns_closure() -> Box<dyn Fn(i32) -> i32> {
    Box::new(|x| x + 1)
}

從根本上來說,宏是一種為寫其他代碼而寫代碼的方式,即所謂的 元編程(metaprogramming)。在附錄 C 中會探討 derive 屬性,其生成各種 trait 的實現(xiàn)。我們也在本書中使用過 println! 宏和 vec! 宏。所有的這些宏以 展開 的方式來生成比你所手寫出的更多的代碼。

元編程對于減少大量編寫和維護(hù)的代碼是非常有用的,它也扮演了函數(shù)扮演的角色。但宏有一些函數(shù)所沒有的附加能力。

一個函數(shù)簽名必須聲明函數(shù)參數(shù)個數(shù)和類型。相比之下,宏能夠接收不同數(shù)量的參數(shù):用一個參數(shù)調(diào)用 println!(“hello”) 或用兩個參數(shù)調(diào)用 println!(“hello {}”, name) 。而且,宏可以在編譯器翻譯代碼前展開,例如,宏可以在一個給定類型上實現(xiàn) trait。而函數(shù)則不行,因為函數(shù)是在運(yùn)行時被調(diào)用,同時 trait 需要在編譯時實現(xiàn)。

實現(xiàn)宏不如實現(xiàn)函數(shù)的一面是宏定義要比函數(shù)定義更復(fù)雜,因為你正在編寫生成 Rust 代碼的 Rust 代碼。由于這樣的間接性,宏定義通常要比函數(shù)定義更難閱讀、理解以及維護(hù)。

宏和函數(shù)的最后一個重要的區(qū)別是:在一個文件里調(diào)用宏 之前 必須定義它,或?qū)⑵湟胱饔糜?,而函?shù)則可以在任何地方定義和調(diào)用。

—https://kaisery.github.io/trpl-zh-cn/ch19-06-macros.html

自定義宏(聲明宏)

接下來我們就直接自定義宏,少說廢話,直接開干(為什么要學(xué)這個?因為甚至可以使用這個自己寫一門語言)

宏的運(yùn)作機(jī)制

研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)

Rust編譯過程

研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)

新建空白宏

創(chuàng)建空白宏的方式很簡單,直接使用macro_rules!進(jìn)行聲明,內(nèi)部形似模式匹配推斷(其實根本就是)

macro_rules! test {
    () => {};
}

宏選擇器

  1. item:條目,例如函數(shù)、結(jié)構(gòu)、模塊等
  2. block:代碼塊
  3. stmt:語句
  4. pat:模式
  5. expr:表達(dá)式
  6. ty:類型
  7. ident:標(biāo)識符
  8. path:路徑,例如 foo、 ::std::mem::replace, transmute::<_, int>, …
  9. meta:元信息條目,例如 #[…]和 #![rust macro…] 屬性
  10. tt:詞條樹
什么是詞條樹

tt詞條樹是指Rust編譯器使用的一種數(shù)據(jù)結(jié)構(gòu),通常用于處理宏(Macro)和代碼生成(Code Generation)。

tt指的是"Token Tree",它是由一系列"Token"構(gòu)成的樹形結(jié)構(gòu)。"Token"是編程語言中最基礎(chǔ)的語法單元,例如關(guān)鍵字、標(biāo)識符、運(yùn)算符、括號等等。而"Token Tree"則是這些"Token"按一定的層次結(jié)構(gòu)排列而成的樹。

在Rust語言中,宏通常是使用tt詞條樹作為輸入,它可以讓宏定義更加靈活和強(qiáng)大。通過對tt詞條樹進(jìn)行遞歸、遍歷和變換,宏可以生成代碼,實現(xiàn)元編程(Metaprogramming)的效果。

除了宏之外,Rust編譯器還會使用tt詞條樹來處理一些代碼生成工作,例如構(gòu)建抽象語法樹(AST)或者生成代碼的中間表示(IR)等等。

宏選擇器設(shè)置各類入?yún)?/h5>

我們通過挑選適合的宏選擇器,才能對應(yīng)我們宏接受的參數(shù)

實現(xiàn)一個log宏

use std::time::{Instant, SystemTime, UNIX_EPOCH};
macro_rules! log {
    ($log_name:tt)=>{
        let now = SystemTime::now();
        let timestamp = now.duration_since(UNIX_EPOCH).unwrap().as_secs();
        println!("=======================start-{}=========================",$log_name);
        println!("----------------createTime:{:?}",timestamp);
        println!("----------------title:{}",$log_name);
        println!("========================end-{}========================",$log_name);
    };
}

fn main() {
    log!("zhangsan");
}

研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)

運(yùn)行重復(fù)模式匹配

當(dāng)我們有多個入?yún)⒌臅r候就需要用到這個了,比如println!這個宏,我們可能會傳入多個需要打印的內(nèi)容,如果各個要取個名字,那么這樣為什么還要去編寫一個統(tǒng)一的,簡化的宏呢?
重復(fù)模式匹配語法:

($($x:expr),*)=>{}
use std::time::{Instant, SystemTime, UNIX_EPOCH};
macro_rules! eq_judge {
    ($($left:expr => $right:expr),*)=>{{
        $(if $left == $right{
            println!("true")
        })*
    }}
}

fn main() {
    eq_judge!(
        "hello"=>"hi",
         "no"=>"no"
    );
}

自定義derive宏(過程宏)

與上面的不一樣的是,這個derive宏標(biāo)注的位置在一般在結(jié)構(gòu)體、enum上
比如:

#[derive(Debug)]
struct a{}

構(gòu)建項目結(jié)構(gòu)(一定要照著做不然會錯)

以下是官方案例,我做了一遍之后重寫順序并強(qiáng)調(diào)犯錯點,請大家一定要按照順序做,遇到錯誤查看我這里寫的錯誤

設(shè)置工作空間

首先隨便創(chuàng)建一個項目,然后修改toml文件

  • hello_macro:聲明需要實現(xiàn)的trait
  • hello_macro_derive:具體的解析,轉(zhuǎn)化,處理邏輯
  • pancakes:主執(zhí)行包
[workspace]
members=[
    "hello_macro","hello_macro_derive","pancakes"
]
創(chuàng)建lib和main
cargo new hello_macro --lib
cargo new hello_macro_derive --lib
cargo new pancakes

結(jié)構(gòu)如下圖:
研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)

hello_macro

lib.rs

書寫需要實現(xiàn)的trait并使用pub暴露

pub trait HelloMacro {
    fn hello_macro();
}

hello_macro_derive

添加依賴和激活proc-macro

syn crate 將字符串中的 Rust 代碼解析成為一個可以操作的數(shù)據(jù)結(jié)構(gòu)。quote 則將 syn 解析的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換回 Rust 代碼。這些 crate 讓解析任何我們所要處理的 Rust 代碼變得更簡單:為 Rust 編寫整個的解析器并不是一件簡單的工作。
proc-macro表示這個cratq是一個proc-macro,增加這個配置以后,這個crate的特性就會發(fā)生一些變化,例如,這個crate將只能對外導(dǎo)出內(nèi)部定義的過程宏,而不能導(dǎo)出內(nèi)部定義的其他內(nèi)容。

cargo add syn
cargo add quote
[package]
name = "hello_macro_derive"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
proc-macro=true

[dependencies]
quote = "1.0.26"
syn = "2.0.15"
lib.rs

#[proc_macro_derive(HelloMacro)]標(biāo)識只要是結(jié)構(gòu)體、enum上標(biāo)注#[derive(HelloMacro)]后就會自動實現(xiàn)HelloMacro這個trait,具體的實現(xiàn)邏輯實際上在impl_hello_macro函數(shù)中

use proc_macro::TokenStream;
use quote::quote;
use syn;

#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    // Construct a representation of Rust code as a syntax tree
    // that we can manipulate
    let ast = syn::parse(input).unwrap();

    // Build the trait implementation
    impl_hello_macro(&ast)
}

fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream {
    let name = &ast.ident;
    let gen = quote! {
        impl HelloMacro for #name {
            fn hello_macro() {
                println!("Hello, Macro! My name is {}!", stringify!(#name));
            }
        }
    };
    gen.into()
}


注意點(請好好讀,官網(wǎng)上說的很清楚了,這個地方一定要搞懂)

當(dāng)用戶在一個類型上指定 #[derive(HelloMacro)]時,hello_macro_derive 函數(shù)將會被調(diào)用。因為我們已經(jīng)使用 proc_macro_derive 及其指定名稱HelloMacro對 hello_macro_derive 函數(shù)進(jìn)行了注解,指定名稱HelloMacro就是 trait 名,這是大多數(shù)過程宏遵循的習(xí)慣。

該函數(shù)首先將來自 TokenStream 的 input 轉(zhuǎn)換為一個我們可以解釋和操作的數(shù)據(jù)結(jié)構(gòu)。這正是 syn 派上用場的地方。syn 中的 parse 函數(shù)獲取一個 TokenStream 并返回一個表示解析出 Rust 代碼的 DeriveInput 結(jié)構(gòu)體。以下展示了從字符串 struct Pancakes; 中解析出來的 DeriveInput 結(jié)構(gòu)體的相關(guān)部分:

DeriveInput {
    // --snip--

    ident: Ident {
        ident: "Pancakes",
        span: #0 bytes(95..103)
    },
    data: Struct(
        DataStruct {
            struct_token: Struct,
            fields: Unit,
            semi_token: Some(
                Semi
            )
        }
    )
}

定義 impl_hello_macro 函數(shù),其用于構(gòu)建所要包含在內(nèi)的 Rust 新代碼。但在此之前,注意其輸出也是 TokenStream。所返回的 TokenStream 會被加到我們的 crate 用戶所寫的代碼中,因此,當(dāng)用戶編譯他們的 crate 時,他們會通過修改后的 TokenStream 獲取到我們所提供的額外功能。

當(dāng)調(diào)用 syn::parse 函數(shù)失敗時,我們用 unwrap 來使 hello_macro_derive 函數(shù) panic。在錯誤時 panic 對過程宏來說是必須的,因為 proc_macro_derive 函數(shù)必須返回 TokenStream 而不是 Result,以此來符合過程宏的 API。這里選擇用 unwrap 來簡化了這個例子;在生產(chǎn)代碼中,則應(yīng)該通過 panic! 或 expect 來提供關(guān)于發(fā)生何種錯誤的更加明確的錯誤信息

pancakes

添加依賴

這里我們需要依賴我們自己寫的lib所以需要用path指明

[package]
name = "pancakes"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
hello_macro = { path = "../hello_macro" }
hello_macro_derive = { path = "../hello_macro_derive" }
main.rs
use hello_macro::HelloMacro;
use hello_macro_derive::HelloMacro;

#[derive(HelloMacro)]
struct Pancakes;

fn main() {
    Pancakes::hello_macro();
}

錯誤

can’t find library marco_t, rename file to src/lib.rs or specify lib.path (為什么不能在單項目包里構(gòu)建)

若你僅僅在一個包中構(gòu)建,當(dāng)你添加[lib] proc-macro = true你會出現(xiàn)以下錯誤:

Caused by:
  can't find library `marco_t`, rename file to `src/lib.rs` or specify lib.path

研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)這說明我們不能把當(dāng)前的包作為lib,因為是主執(zhí)行包
原理︰考慮過程宏是在編譯一個crate之前,對crate的代碼進(jìn)行加工的一段程序,這段程序也是需要編譯后執(zhí)行的。如果定義過程宏和使用過程宏的代碼寫在一個crate中,那就陷入了死鎖:
要編譯的代碼首先需要運(yùn)行過程宏來展開,否則代碼是不完整的,沒法編譯crate.
不能編譯crate,crate中的過程宏代碼就沒法執(zhí)行,就不能展開被過程宏裝飾的代碼

can’t use a procedural macro from the same crate that defines it

那假如直接去掉不管這個,你會看到這個錯誤,意味著你必須將過程宏構(gòu)建在lib中
研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)

自定義類屬性宏(個人認(rèn)為最重要)

類屬性宏與自定義派生宏相似,不同的是 derive 屬性生成代碼,它們(類屬性宏)能讓你創(chuàng)建新的屬性。它們也更為靈活;derive 只能用于結(jié)構(gòu)體和枚舉;屬性還可以用于其它的項,比如函數(shù)

常見于各類框架中!

一個簡單的例子

項目包結(jié)構(gòu)

同自定義過程宏
我們需要把正在的解析處理邏輯放在lib下

[workspace]
members=[
"json_marco","json_test"
]
json_marco
添加依賴
[package]
name = "json_marco"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1.0.56"
quote = "1.0.26"
syn = { version = "2.0.15", features = ["full"] }

編寫lib
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_attribute]
pub fn my_macro(attr:TokenStream,item:TokenStream)->TokenStream{
    println!("test");
    println!("{:#?}",attr);
    println!("{:#?}",item);
    item
}

這很簡單就是單純輸出一下

json_test

toml映引入

[package]
name = "json_test"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
json_marco={path= "../json_marco"}

main.rs文章來源地址http://www.zghlxwxcb.cn/news/detail-432616.html

use json_marco::my_macro;

#[my_macro("test111")]
fn test(a: i32) {
    println!("{}", a);
}

fn main() {
    test(5);
}

一些例子

base
lib
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_attribute]
pub fn my_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
    // 解析輸入的類型
    let input = parse_macro_input!(item as DeriveInput);
    
    // 獲取類型名
    let name = input.ident;

    // 構(gòu)建實現(xiàn)代碼
    let expanded = quote! {
        impl #name {
            fn my_function(&self) {
                println!("This is my custom function!");
            }
        }
    };
    
    // 將生成的代碼轉(zhuǎn)換回 TokenStream 以供返回
    TokenStream::from(expanded)
}

main
#[my_macro]
struct MyStruct {
    field1: u32,
    field2: String,
}

fn main() {
    let my_instance = MyStruct { field1: 42, field2: "hello".to_string() };
    my_instance.my_function();
}

flaky_test
lib
extern crate proc_macro;
extern crate syn;
use proc_macro::TokenStream;
use quote::quote;

#[proc_macro_attribute]
pub fn flaky_test(_attr: TokenStream, input: TokenStream) -> TokenStream {
  let input_fn = syn::parse_macro_input!(input as syn::ItemFn);
  let name = input_fn.sig.ident.clone();
  TokenStream::from(quote! {
    #[test]
    fn #name() {
      #input_fn

      for i in 0..3 {
        println!("flaky_test retry {}", i);
        let r = std::panic::catch_unwind(|| {
          #name();
        });
        if r.is_ok() {
          return;
        }
        if i == 2 {
          std::panic::resume_unwind(r.unwrap_err());
        }
      }
    }
  })
}
main
#[flaky_test::flaky_test]
fn my_test() {
  assert_eq!(1, 2);
}
json_parse
lib.rs
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields};

#[proc_macro_attribute]
pub fn serde_json(_args: TokenStream, input: TokenStream) -> TokenStream {
    // 將輸入解析為 DeriveInput 類型,這是所有 Rust 結(jié)構(gòu)體和枚舉的通用 AST
    let input = parse_macro_input!(input as DeriveInput);

    // 檢查這是否是一個結(jié)構(gòu)體,并拿到它的名稱、字段列表等信息
    let struct_name = input.ident;
    let fields = match input.data {
        Data::Struct(data_struct) => data_struct.fields,
        _ => panic!("'serde_json' can only be used with structs!"),
    };

    // 生成代碼,將結(jié)構(gòu)體轉(zhuǎn)換為 JSON 字符串
    let output = match fields {
        Fields::Named(fields_named) => {
            let field_names = fields_named.named.iter().map(|f| &f.ident);
            quote! {
                impl #struct_name {
                    pub fn to_json(&self) -> String {
                        serde_json::to_string(&json!({
                            #(stringify!(#field_names): self.#field_names,)*
                        })).unwrap()
                    }
                }
            }
        }
        Fields::Unnamed(fields_unnamed) => {
            let field_indices = 0..fields_unnamed.unnamed.len();
            quote! {
                impl #struct_name {
                    pub fn to_json(&self) -> String {
                        serde_json::to_string(&json!([
                            #(self.#field_indices,)*
                        ])).unwrap()
                    }
                }
            }
        }
        Fields::Unit => {
            quote! {
                impl #struct_name {
                    pub fn to_json(&self) -> String {
                        serde_json::to_string(&json!({})).unwrap()
                    }
                }
            }
        }
    };

    // 將生成的代碼作為 TokenStream 返回
    output.into()
}

main.rs
#[serde_json]
struct MyStruct {
    name: String,
    age: u32,
}

fn main() {
    let my_struct = MyStruct {
        name: "Alice".to_string(),
        age: 25,
    };
    let json_str = my_struct.to_json();
    println!("JSON string: {}", json_str);
}

fn_time
lib
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemFn};

#[proc_macro_attribute]
pub fn run(_args: TokenStream, input: TokenStream) -> TokenStream {
    // 將輸入解析為函數(shù)節(jié)點
    let input = parse_macro_input!(input as ItemFn);

    // 獲取函數(shù)名稱、參數(shù)列表等信息
    let func_name = &input.ident;
    let func_args = &input.decl.inputs;

    // 生成代碼,在函數(shù)開始和結(jié)束時分別打印時間戳
    let output = quote! {
        #input

        fn #func_name(#func_args) -> () {
            println!("{} started", stringify!(#func_name));
            let start = std::time::Instant::now();
            let result = #func_name(#func_args);
            let end = start.elapsed();
            println!("{} finished in {}ms", stringify!(#func_name), end.as_millis());
            result
        }
    };

    // 將生成的代碼作為 TokenStream 返回
    output.into()
}

main
#[run]
fn my_function() -> i32 {
    // 模擬一些處理時間
    std::thread::sleep(std::time::Duration::from_secs(1));
    42
}

fn main() {
    let result = my_function();
    println!("Result = {}", result);
}

到了這里,關(guān)于研讀Rust圣經(jīng)解析——Rust learn-16(高級trait,宏)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【Rust 基礎(chǔ)篇】Rust 特征(Traits)

    Rust 的特征(Traits)是一種強(qiáng)大的語言機(jī)制,它允許我們定義共享行為并實現(xiàn)代碼的抽象。通過特征,我們可以編寫更加靈活和可復(fù)用的代碼。本篇博客將詳細(xì)介紹 Rust 特征的定義、實現(xiàn)和使用方法,包括特征的基本語法、默認(rèn)實現(xiàn)、泛型特征以及特征的實現(xiàn)和使用。 在 Ru

    2024年02月15日
    瀏覽(19)
  • Rust-trait

    Rust-trait

    Rust語言中的trait是非常重要的概念。 在Rust中,trait這一個概念承擔(dān)了多種職責(zé)。在中文里,trait可以翻譯為“特征”“特點”“特性”等。 trait中可以定義函數(shù)。用例子來說明,我們定義如下的trait: 上面這個trait包含了一個方法,這個方法只有一個參數(shù),這個self參數(shù)是什么意

    2024年01月20日
    瀏覽(38)
  • 【Rust 基礎(chǔ)篇】Rust Deref Trait 的使用

    在 Rust 中,Deref trait 是一種特殊的 trait,用于重載解引用操作符 * 。通過實現(xiàn) Deref trait,我們可以定義類型的解引用行為,使其在使用 * 運(yùn)算符時表現(xiàn)得像引用類型。 本篇博客將詳細(xì)介紹 Rust 中如何實現(xiàn)和使用 Deref trait,以及它在代碼中的應(yīng)用場景。 Deref trait 的定義如下:

    2024年02月17日
    瀏覽(30)
  • rust學(xué)習(xí)-泛型和trait

    Option,Vec,HashMapK, V,ResultT, E等,取函數(shù)以減少代碼重復(fù)的機(jī)制 兩個函數(shù),不同點只是名稱和簽名類型 重寫如下 為所有類型的結(jié)構(gòu)體提供方法 只為f32提供方法 方法使用了與結(jié)構(gòu)體定義中不同類型的泛型 Rust 實現(xiàn)了泛型,使得使用泛型類型參數(shù)的代碼相比使用具體類型并沒

    2024年02月17日
    瀏覽(15)
  • Rust語法: 枚舉,泛型,trait

    這是我學(xué)習(xí)Rust的筆記,本文適合于有一定高級語言基礎(chǔ)的開發(fā)者看不適合剛?cè)腴T編程的人,對于一些概念像枚舉,泛型等,不會再做解釋,只寫在Rust中怎么用。 枚舉的定義與賦值 枚舉的定義格式如下: enum 枚舉名{ 值1(附加類型), 值2(附加類型),… } 其中,關(guān)聯(lián)類型可以省去

    2024年02月13日
    瀏覽(23)
  • 【Rust 基礎(chǔ)篇】Rust Trait 實現(xiàn):靈活的接口抽象

    Rust是一種以安全性和高效性著稱的系統(tǒng)級編程語言,其設(shè)計哲學(xué)是在不損失性能的前提下,保障代碼的內(nèi)存安全和線程安全。為了實現(xiàn)這一目標(biāo),Rust引入了\\\"所有權(quán)系統(tǒng)\\\"、\\\"借用檢查器\\\"等特性,有效地避免了常見的內(nèi)存安全問題。然而,在編程中我們常常需要實現(xiàn)多態(tài)和抽象

    2024年02月15日
    瀏覽(26)
  • 30天拿下Rust之Trait

    概述 ????????在Rust中,Trait是一個核心概念,它允許我們定義類型應(yīng)該具有的行為。Trait類似于其他語言中的接口,但Rust的Trait更為強(qiáng)大和靈活。它不僅定義了一組方法,還允許我們指定方法的默認(rèn)實現(xiàn)、泛型約束和繼承。通過Trait,我們可以定義一組方法的簽名和關(guān)聯(lián)類

    2024年03月17日
    瀏覽(23)
  • 【Rust 基礎(chǔ)篇】Rust派生宏:自動實現(xiàn)trait的魔法

    Rust是一門現(xiàn)代的、安全的系統(tǒng)級編程語言,它提供了豐富的元編程特性,其中派生宏(Derive Macros)是其中之一。派生宏允許開發(fā)者自定義類型上的trait實現(xiàn),從而在編譯期間自動實現(xiàn)trait。在本篇博客中,我們將深入探討Rust中的派生宏,包括派生宏的定義、使用方法以及一些

    2024年02月14日
    瀏覽(17)
  • Rust之泛型、trait與生命周期

    泛型是具體類型或其他屬性的抽象替代。在編寫代碼時,可以直接描述泛型的行為,或者它與其他泛型產(chǎn)生的聯(lián)系,而無須知曉它在編譯和運(yùn)行代碼時采用的具體類型。 們可以在聲明函數(shù)簽名或結(jié)構(gòu)體等元素時使用泛型,并在隨后搭配不同的具體類型來使用這些元素。 當(dāng)使

    2024年02月13日
    瀏覽(25)
  • Rust系列(四) trait備忘錄(持續(xù)更新)

    上一篇:Rust系列(三) 類型系統(tǒng)與trait 基于官方文檔進(jìn)行簡單學(xué)習(xí)記錄,保證所有示例是可運(yùn)行的基本單元。測試 rust 程序除了使用官方的 playground 之外,還可以通過定義 [[example]] 來運(yùn)行程序。 用于 不可變對象 的解引用操作,語法類似 *v 。 官方文檔: https://doc.rust-lang.org

    2024年02月14日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包