2014-02-25 74 views
3

我嘗試用封口:傳遞一個閉合兩次沒有它得到搬走

fn call_it(f: ||) { 
    f(); 
} 
let klosure = || println("closure!"); 
call_it(klosure); 
call_it(klosure); //Blows up here 

傳遞klosure到call_it()兩次導致賬戶上的截流值的編譯器錯誤得到感動:

closures.rs:16:13: 16:20 error: use of moved value: `klosure` 
closures.rs:16  call_it(klosure); 
          ^~~~~~~ 
closures.rs:15:13: 15:20 note: `closure` moved here because it has type `||`, which is a non-copyable stack closure (capture it in a new closure, e.g. `|x| f(x)`, to override) 
closures.rs:15  call_it(klosure); 
          ^~~~~~~ 

編譯器實際上提出了一個關於如何解決該問題的建議,但我還沒有想出成功應用它的方法。

有什麼建議嗎? :D

回答

2

注意:`closure`移動到這裏是因爲它有一個`||`,它是一個不可複製的堆棧閉包(捕獲它在一個新的閉包中,例如`| x | f(x) ,重寫)

這意味着你會寫|| closure()而不是closure:你傳遞一個新的封閉它要求你的第一封。

0

(更新:。不這樣做,它可能會在不久的將來被禁止一個&mut ||可能會工作得很好,現在和將來查看這個答案在評論中討論和鏈接)

另一種可能的方法(雖然有點醜閱讀):

fn call_it(f_ref: &||) { // now takes a borrowed reference to a closure 
    (*f_ref)(); 
} 
let klosure = || println("closure!"); 
call_it(&klosure); 
call_it(&klosure); 
+0

是不是應該不正確的,通過調用一個關閉一個'&'(出於同樣的原因是不正確的變異了'&& MUT T' )?例如。它允許一個[重新創建「反覆關閉的情況」](https://gist.github.com/huonw/a2134c85f1ecf2c9ef04)。 (我與Niko談過這件事,他提到我[#12224](https://github.com/mozilla/rust/issues/12224)。) – huon

+0

啊,你可能是對的。對於旁觀者來說,最初的「經常性關閉」案例是http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/ – pnkfelix

相關問題