使用Rust寫乙個累加器

2021-10-05 15:08:44 字數 1493 閱讀 1642

需求如下:有乙個函式 foo,接受引數 n,返回乙個閉包;該閉包接受引數 i,返回 n + i。

用法:

let f = foo(n); // 得到乙個閉包

let v = f(i);   // 呼叫閉包並傳入引數i,得到值v

具體型別版本總是比泛型版本更容易理解,因此我的第乙個版本是具體型別的,它只接受 i32 型別,並且工作的很好:

fn foo(n: i32) -> boxi32> 

fn main()

接下來嘗試寫乙個泛型版本,把型別 i32 換成泛型引數 t:

fn foo2(n: t) -> boxt>
很可惜,編譯器抱怨說不能把型別 t 與型別 t 相加:

error[e0369]: cannot add `t` to `t`

--> src\main.rs:25:25

|25 |     box::new(move |i| n + i)

|                       - ^ - t

|                       |

|                       t

|= note: `t` might need a bound for `std::ops::add`

很奇怪吧,t 不能與 t 相加。我們知道 rust 有乙個強大的 trait 系統,使用 trait 對引數進行約束,rust 中已經定義了 std::ops::add 這個 trait,只有實現了該 trait 的型別,才能執行加法。於是第二個版本的泛型函式如下所示:

fn foo2>(n: t) -> boxt>
這次,編譯器報怨說 t 的生命週期不夠長:

error[e0310]: the parameter type `t` may not live long enough

--> src\main.rs:25:5

|24 | fn foo2>(n: t) -> boxt>

有經驗的同學可能意識到了,這個版本仍然存在問題:

error[e0507]: cannot move out of `n`, a captured variable in an `fn` closure

--> src\main.rs:25:23

|24 | fn foo2>(n: t) -> boxt>

這次編譯器不再報怨了,它能夠正常的執行了:

fn main()
回過頭來,繼續思考,泛型版本為啥必須給引數 t 加上靜態生命週期約束呢?

我的答案是,既然是泛型,只要是實現了 add 和 copy 這兩個 trit 的型別,都可以作為 foo2 的引數;如果該型別的生命週期是 'static 時,這種情況也是要支援的,所以給泛型 t 加上 'static 約束也就順理成章了。

SparkCore之累加器的使用

2.自定義累加器 使用spark自帶的常用累加器的步驟 1 需求 給出乙個集合,list a 1 a 2 a 3 a 4 來統計單詞出現的次數,期望的輸出結果 a,10 2 需求分析 1 沒有使用累加器的情況 2 使用累加器的情況 3 實現 import org.apache.spark.rdd.r...

Spark累加器的作用和使用

不經過shuffle,實現詞頻統計 bject spark06 accumulator 累加器的tostring方法 println sumacc 取出累加器中的值 println sumacc.value sc.stop 不經過shuffle,計算以h開頭的單詞出現的次數。object spark...

用rust寫乙個玩具直譯器0

假期閒來無事,看了thorsten ball的writing an interpreter in go,他還有一本寫編譯器的暫時沒看,跟著書上的 寫了一遍,想著用rust重寫一遍,現在正在寫eval部分.writing an interpreter in go 我對go的感覺如它宣傳的一般,21世紀...