自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go不能寫,但是可以用Rust寫的三段代碼!

開發(fā) 前端
Rust通過在編譯時而不是運行時檢測錯誤來確保可靠性,實現(xiàn)高性能,并且具有一定程度的表達性,使其可以編寫其他語言無法編寫的代碼。?

在這篇文章中,要分享的例子不僅僅是假設,它們來自于工作中的真實案例,在這些例子中,Go的局限性無法實現(xiàn)所需的解決方案。聲明:這里的區(qū)別并不在于Rust代碼比Go代碼更正確或更快。

1.讀取線程的ID

記錄當前線程的ID,或者在Go的情況下,記錄協(xié)程ID,是非常有用的。它明確了哪個線程正在做什么。如果沒有這些信息,每個線程的活動就會交織在一個日志文件中,因此很難跟蹤單個執(zhí)行流。

在Rust中,獲取線程id就像這樣簡單:

let id = thread::current().id();

然而,Go并不公開協(xié)程id。Go故意不公開協(xié)程id,以阻止開發(fā)人員對線程本地存儲進行編程。對于想要理解日志的開發(fā)人員必須求助于其他方法來檢索該信息。

2.單個Select語句中的Case優(yōu)先級排序

Go在select-case語句(等待多個通道操作)中隨機選擇所有就緒中的一個。如果準備好了多個case,并且希望在單個select語句中優(yōu)先執(zhí)行一個case,則不行。

在下面的代碼中,nReady1在統(tǒng)計上等于nReady2。

func main() {
    ready1 := make(chan struct{})
    close(ready1)
    ready2 := make(chan struct{})
    close(ready2)

    nReady1 := 0
    nReady2 := 0
    N := 10_000
    for i := 0; i < N; i++ {
        select {
        case <-ready1:
           nReady1++
        case <-ready2:
           nReady2++
        }
    }
    fmt.Println("nReady1:", nReady1)
    fmt.Println("nReady2:", nReady2)
}

執(zhí)行結果:

nReady1: 4943
nReady2: 5057

必須使用嵌套的select語句(帶有默認值)來實現(xiàn)優(yōu)先級。

select {
    case <-ready1:
       nReady1++
    default:
       select {
          case <-ready1:
             nReady1++
          case <-ready2:
             nReady2++
       }
}

然而,Rust的異步運行時Tokio允許在單個select語句中使用biased關鍵字設置優(yōu)先級順序。

在下面的例子中,按照它們在代碼中出現(xiàn)的順序排列優(yōu)先級。

use tokio::sync::mpsc;
use tokio::select;

#[tokio::main]
async fn main() {
    let (tx1, mut rx1) = mpsc::channel::<()>(1);
    drop(tx1);
    let (tx2, mut rx2) = mpsc::channel::<()>(1);
    drop(tx2);

    let mut n_ready1 = 0;
    let mut n_ready2 = 0;
    let n = 10_000;
    for _ in 0..n {
        select! {
            biased; // 按出現(xiàn)的順序優(yōu)先處理已準備好的case
            _ = rx1.recv() => {
                n_ready1 += 1;
            },
            _ = rx2.recv() => {
                n_ready2 += 1;
            },
        }
    }

    println!("n_ready1: {}", n_ready1);
    println!("n_ready2: {}", n_ready2);
}

執(zhí)行結果:

n_ready1: 10000
n_ready2: 0

Rust使用單個select語句實現(xiàn)了對case的優(yōu)先級排序。

3.具有指針和值接收器的泛型類型

在Go中,你想為類型參數(shù)S定義一個類型約束,它實現(xiàn)了兩個方法:

type S struct{}

func (s S) M()  {}
func (s *S) P() {}

不幸的是,不可能用單個類型約束指定這兩個方法。必須使用兩個單獨的類型參數(shù),每個類型參數(shù)都有自己的約束,然后將它們鏈接到函數(shù)f中。首先,定義T受Mer接口類型的約束。然后,將PT定義為受Per[T]接口類型約束,并引用第一個T。這看起來很復雜,并不直觀。

type Per[T any] interface {
    P()
    *T // 非接口類型約束元素
}

type Mer interface {
    M()
}

func f[T Mer, PT Per[T]](t T) {
    PT(&t).P()
    t.M()
}

在Rust中,解決方案很簡單。定義一個單獨的trait:MyTrait,然后將它用作f中的一個trait綁定。

trait MyTrait {
    fn M(&self);
    fn P(&mut self);
}

struct S;

impl MyTrait for S {
     fn M(&self) {}
    fn P(&mut self) {}
}

fn f<T: MyTrait>(t: &mut T) {
    t.M();
    t.P();
}

總結

Rust通過在編譯時而不是運行時檢測錯誤來確??煽啃?,實現(xiàn)高性能,并且具有一定程度的表達性,使其可以編寫其他語言無法編寫的代碼。

責任編輯:武曉燕 來源: coding到燈火闌珊
相關推薦

2021-11-16 12:25:14

jsPPT前端

2024-06-12 08:00:07

2023-01-30 08:04:28

程序隱藏debug

2023-04-03 08:26:01

systemd運維

2023-06-19 14:14:24

Rust程序Web

2024-01-18 13:36:00

RustGo開發(fā)

2023-02-20 08:00:02

Rust語言系統(tǒng)

2011-12-26 09:34:26

2019-01-04 15:37:41

折疊手機小米手機

2010-03-04 16:33:21

Ubuntu cvs

2018-07-31 10:20:54

WindowsDocker Linux

2011-02-25 10:12:09

GoWeb

2023-03-10 08:48:29

2020-11-09 14:15:23

代碼菜鳥老司機

2011-01-21 13:56:44

SendmailSolaris

2011-01-04 14:27:50

安裝linux方法

2012-03-19 15:44:39

代碼

2023-04-10 11:22:34

CIOIT運營成本

2021-09-05 23:47:55

手機功能智能

2009-12-14 10:57:34

Ruby調試器
點贊
收藏

51CTO技術棧公眾號