2015-06-27 61 views
9

我現在正在學習Rust,看來我無法將閉包指定爲函數參數。下面是我有:無法將閉包作爲參數

fn foo(a: i32, f: |i32| -> i32) -> i32 { 
    f(a) 
} 

fn main() { 
    let bar = foo(5, |x| { x + 1 }); 
    println!("{}", bar); 
} 

我得到以下錯誤:

foo.rs:1:19: 1:20 error: expected type, found `|` 
foo.rs:1 fn foo(a: i32, f: |i32| -> i32) -> i32 { 

好了,所以它不喜歡封閉的語法。這是有點煩人,因爲現在我必須寫這個:

fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 { 
    f(a) 
} 

fn main() { 
    let bar = foo(5, Box::new(|x| { x + 1 })); 
    println!("{}", bar); 
} 

那麼發生了什麼?我讀過幾個不同的places,第一個例子是有效的,所以這個「閉包類型參數」的語法被刪除,或者我只是做錯了什麼?

回答

6

鐵鏽從一開始就被開發出來,從那以後,鐵鏽已經發展了很多。您鏈接到的堆棧溢出文章已近1年,在1.0版之前的版本中,Rust的時間長達一生......(雙關語意思)

最直接的答案是:請記住,很多文章,博客帖子,SO答案......都不再相關,因爲語言發生了變化。如果你嘗試了一個解決方案,但它不起作用,只需找到更新的語法(就像你做的那樣!)然後繼續前進。

對於這種特定情況,this RFC記錄從|...| -> ...Fn/FnMut/FnOnce(...) -> ...的變化。

順便說一句,有一個社區努力找到過時的文章,並明確標記爲不推薦使用,以避免這一特定問題的計劃。雖然我找不到鏈接。

+1

[RFC 114](https://github.com/rust-lang/rfcs/blob/master/text/0114-closures.md)與RFC 231相關的更多,但RFC 114的細節不是最新的(例如,「Fn」現在是「FnMut」,而「FnShare」現在是「Fn」)。 –

+0

*明確表示將其標記爲已棄用* - 或者只是要求其他答覆者更新答案^ _ ^。我這樣做了,幾分鐘後就更新了。現在,這個問題應該被標記爲重複? – Shepmaster

+0

我沒有記住SO,而是博客文章,其中的內容不是可更新的社區。它甚至可能是不受歡迎的;例如Niko Matsakis的博客文章更多的是關於思考過程 - 你會保留它作爲歷史參考,而不是最新的文檔。 – mdup

4

如果有人有興趣今天在這個問題上,這裏與泛型語法:

fn foo<F: Fn(i32) -> i32>(a: i32, f: F) -> i32 { 
    f(a) 
} 

fn main() { 
    let bar = foo(5, |x| { x + 1 }); 
    println!("{}", bar); 
} 

或者,使用特質對象:

fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 { 
    f(a) 
} 

fn main() { 
    let bar = foo(5, Box::new(|x| { x + 1 })); 
    println!("{}", bar); 
} 

你應該更喜歡前者。

相關問題