2014-10-26 29 views
10

我想寫一個int -returning函數,它接受一個採用零參數的閉包,一個採用一個參數的閉包和一個帶兩個參數的閉包,其中所有閉包參數都是鍵入int,每個關閉返回f32如何在Rust中的簽名中使用Fn特徵

這個函數的簽名是什麼樣的?

現在我想通過FnFnMut性狀接受。簽名是什麼樣的?是否需要使用箱子中的功能?如果是這樣,那爲什麼?

如果知道:它看起來像什麼糖?脫?

如果知道:未來可能會發生什麼變化?

回答

9

我想寫一個接受封閉 採取零個論點,一個封閉帶一個參數的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(並刪除mutf1f2f3)如果你想強制呼叫者通過不會改變其環境的關閉,但總的來說,我認爲,你會想要使用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); 
} 

實際(FnMutFnFnOnce)將被推斷出來。

還會有其他更改,如move關鍵字用於從函數返回的閉包(move影響變量捕獲語義)。這包括在this接受RFC。

一般來說,無盒子關閉概述在this RFC中。然而,它沒有更新,新的關閉糖語法和其他微妙的變化;遵循Rust issue tracker可能更好,以瞭解更多信息。例如,有很多關閉盒子的問題彙總在this錯誤中。

+0

呵呵。我正在通過RFC試圖找到有關Fn特徵的信息,我想我錯過了它,因爲我正在尋找'特徵'而不是'閉包'。謝謝! – user 2014-10-26 21:35:10

+0

是的,這些東西被稱爲拆箱關閉,如果你尋找這個詞,你會發現很多東西。 – 2014-10-26 21:43:35

4

FnFnMutFnOnce是引入了非盒裝閉包的三種特徵類型。這些特性之間的區別,除了他們的單一方法的名稱,是對這些方法的self參數傳遞不同:

  • Fn&self(參考,不能變異封閉的環境)
  • FnMut&mut self(參照,可以發生變異封閉的環境)
  • FnOnceself(按價值計算,所消耗的關閉,所以封閉只能被調用一次)

這些特徵有兩個類型參數: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上的拆箱關閉中的錯誤。

相關問題