2014-11-22 85 views
9

鉴于以下锈程序:如何通过一个函数作为参数拉斯特

fn call_twice<A>(val: A, f: fn(A) -> A) -> A { 
    f(f(val)) 
} 

fn main() { 
    fn double(x: int) -> int {x + x}; 
    println!("Res is {}", call_twice(10i, double)); 
    // println!("Res is {}", call_twice(10i, (x: int) -> int {x + x})); 
    //^this line will fail 
} 

我为什么可以通过double的功能,而不是内联?没有在某处定义函数,实现相同行为的好方法是什么?

回答

13

2016年4月1日更新:

铁锈1.0,代码应该是这样的:

fn call_twice<A, F>(val: A, mut f: F) -> A 
where F: FnMut(A) -> A { 
    let tmp = f(val); 
    f(tmp) 
} 

fn main() { 
    fn double(x: i32) -> i32 {x + x}; 
    println!("Res is {}", call_twice(10, double)); 
    println!("Res is {}", call_twice(10, |x| x + x)); 
} 

变化到封闭的参数是因为封闭现在拆箱。

原文:

据我所知,你不能定义内联函数这样。

什么你是一个封闭。以下作品:

fn call_twice<A>(val: A, f: |A| -> A) -> A { 
    let tmp = f(val); 
    f(tmp) 
} 

fn main() { 
    fn double(x: int) -> int {x + x}; 
    println!("Res is {}", call_twice(10i, double)); 
    println!("Res is {}", call_twice(10i, |x| x + x)); 
} 

这里有几点需要注意:

  1. 功能强迫工厂倒闭,但相反的是不正确的。

  2. 您需要的f(val)结果在临时存储由于借贷规则。短版本:您需要独立访问闭包来调用它,借用检查程序不够聪明,无法实现这两个调用在原始位置是独立的。

  3. 关闭正在被替换为取消封闭关闭,所以这将在未来发生变化,但我们还没有完成。

+0

感谢您的解释。这个临时变量有点奇怪,但我认为这会在更稳定的版本中修复。 – 2014-11-23 09:21:24

+0

这似乎并不具有防锈1.7的工作:https://play.rust-lang.org/?gist=ad35b80eeae1d1966944a66a75d0ad80&version=stable – 2016-03-31 14:48:09

+2

@SandeepDatta这个答案是在2014年;即使在Rust 1.0上,该代码也会失效。我已经更新了它。 – 2016-04-01 01:18:13

相关问题