需求如下:有乙個函式 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世紀...