我想寫一個int
-returning函數,它接受一個採用零參數的閉包,一個採用一個參數的閉包和一個帶兩個參數的閉包,其中所有閉包參數都是鍵入int
,每個關閉返回f32
。如何在Rust中的簽名中使用Fn特徵
這個函數的簽名是什麼樣的?
現在我想通過Fn
和FnMut
性狀接受。簽名是什麼樣的?是否需要使用箱子中的功能?如果是這樣,那爲什麼?
如果知道:它看起來像什麼糖?脫?
如果知道:未來可能會發生什麼變化?
我想寫一個int
-returning函數,它接受一個採用零參數的閉包,一個採用一個參數的閉包和一個帶兩個參數的閉包,其中所有閉包參數都是鍵入int
,每個關閉返回f32
。如何在Rust中的簽名中使用Fn特徵
這個函數的簽名是什麼樣的?
現在我想通過Fn
和FnMut
性狀接受。簽名是什麼樣的?是否需要使用箱子中的功能?如果是這樣,那爲什麼?
如果知道:它看起來像什麼糖?脫?
如果知道:未來可能會發生什麼變化?
我想寫一個接受封閉 採取零個論點,一個封閉帶一個參數的int-恢復功能,以及封閉 取兩個參數,所有的封閉參數的數據類型爲int和 每關閉返回f32。
這個函數的簽名是什麼樣的?
函數簽名,目前它的使用(2014年10月26日晚間)看起來是這樣的:
#![feature(unboxed_closures, unboxed_closure_sugar, overloaded_calls)]
fn closures<F1, F2, F3>(mut f1: F1, mut f2: F2, mut f3: F3) -> int
where F1: FnMut() -> f32,
F2: FnMut(int) -> f32,
F3: FnMut(int, int) -> f32 {
(f1() + f2(10) + f3(20, 30)) as int
}
fn main() {
let x = closures(
|&mut:| 0.1,
|&mut: x: int| (2*x) as f32,
|&mut: x: int, y: int| (x + y) as f32
);
println!("{}", x);
}
可以使用Fn
代替FnMut
(並刪除mut
前f1
,f2
和f3
)如果你想強制呼叫者通過不會改變其環境的關閉,但總的來說,我認爲,你會想要使用FnMut
。
此代碼使用無盒封閉糖和重載調用。沒有他們,就應該是這樣的:
#![feature(unboxed_closures)]
fn closures<F1, F2, F3>(mut f1: F1, mut f2: F2, mut f3: F3) -> int
where F1: FnMut<(), f32>,
F2: FnMut<(int,), f32>,
F3: FnMut<(int, int), f32> {
(f1.call_mut(()) + f2.call_mut((10,)) + f3.call_mut((20, 30))) as int
}
fn main() {
let x = closures(
|&mut:| 0.1,
|&mut: x: int| (2*x) as f32,
|&mut: x: int, y: int| (x + y) as f32
);
println!("{}", x);
}
糖是用來美化閉合型的語法,和重載來電功能允許省略明確call_*
方法。
至於發生了什麼事情在將來改變,那麼它很可能是封閉施工語法將被簡化(當電流關閉被丟棄),所以main()
位將是這樣的:
fn main() {
let x = closures(
|| 0.1,
|x| (2*x) as f32,
|x, y| (x + y) as f32
);
println!("{}", x);
}
實際(FnMut
,Fn
或FnOnce
)將被推斷出來。
還會有其他更改,如move
關鍵字用於從函數返回的閉包(move
影響變量捕獲語義)。這包括在this接受RFC。
一般來說,無盒子關閉概述在this RFC中。然而,它沒有更新,新的關閉糖語法和其他微妙的變化;遵循Rust issue tracker可能更好,以瞭解更多信息。例如,有很多關閉盒子的問題彙總在this錯誤中。
Fn
,FnMut
和FnOnce
是引入了非盒裝閉包的三種特徵類型。這些特性之間的區別,除了他們的單一方法的名稱,是對這些方法的self
參數傳遞不同:
Fn
:&self
(參考,不能變異封閉的環境)FnMut
:&mut self
(參照,可以發生變異封閉的環境)FnOnce
:self
(按價值計算,所消耗的關閉,所以封閉只能被調用一次)這些特徵有兩個類型參數:Args
,這是一個元組類型,表示封閉的參數(或()
,如果封閉不帶參數)和Result
(封閉的返回類型)。
現在回答你的問題:
閉幕採取零參數:
fn foo<F>(closure: F) -> int where F: Fn<(), f32> {
0
}
fn foo<F: Fn<(), f32>>(closure: F) -> int {
0
}
另外,結合可以使用where
條款寫入
封帶一個參數:
fn foo<F: Fn<(int), f32>>(closure: F) -> int {
0
}
封帶有兩個參數:
fn foo<F: Fn<(int, int), f32>>(closure: F) -> int {
0
}
閉幕採取零個參數,加糖形式:
fn foo<F: Fn() -> f32>(closure: F) -> int {
0
}
封帶一個參數,加糖形式:
fn foo<F: Fn(int) -> f32>(closure: F) -> int {
0
}
封帶有兩個參數,加糖形式:
fn foo<F: Fn(int, int) -> f32>(closure: F) -> int {
0
}
老 「盒裝」 倒閉潮會消失。您可以跟蹤metabug上的拆箱關閉中的錯誤。
呵呵。我正在通過RFC試圖找到有關Fn特徵的信息,我想我錯過了它,因爲我正在尋找'特徵'而不是'閉包'。謝謝! – user 2014-10-26 21:35:10
是的,這些東西被稱爲拆箱關閉,如果你尋找這個詞,你會發現很多東西。 – 2014-10-26 21:43:35