Rust: func as function arg
在很久很久以前, 其实特么也不是很久, rust以前能直接用closure作为参数类型传参,结果现在在rustc 1.5下试了一下, 根本不行啊:
fncall_fun f: |i32| -> i32) { // error: expected type, found `|`
println!("call func got res: {}", f(32));
}
fncall_function function: fn(u8) -> bool) -> bool { // fix error of the above
function(8)
}
fnmain ) {
let max = 5;
let closure = move |arg: u8| { arg < max };
println!("{}", call_function(closure));
}
// 编译会产生下面的错误
// test.rs:18:34: 18:41 error: mismatched types:
// expected `fn(u8) -> bool`,
// found `[closure@tt.rs:17:19: 17:47 max:_]`
// (expected fn pointer,
// found closure) [E0308]
// tt.rs:18 println!("{}", call_function(closure));
// ^~~~~~~
只能说以前看到的rust语法已经在后续的发展中修改了。
那么我们现在变成这样的做法了:
fncall_function function: fn(u8) -> bool) -> bool {
function(8)
}
fnmy_local_function arg: u8) -> bool{
let max = 5;
arg < max
}
fnmain ) {
println!("{}", call_function(my_local_function));
}
它的泛型用法:
fncall_function function: fn(u8) -> bool) -> bool {
function(8)
}
fnmy_local_function arg: u8) -> bool{
let max = 5;
arg < max
}
fnmain ) {
println!("{}", call_function(my_local_function));
fndouble x: i32) -> i32 {x + x}; // Ok
println!("Res is {}", call_twice(10i32, double)); // OK
let closure = |x: i32| -> i32 {x + x};
println!("Closure res is {}", call_twice(10i32, closure));
}
fncall_twice<A, F> val: A, f: F) -> A where F: Fn(A)->A {
let tmp = f(val);
f(tmp)
}
总的说, 就是函数声明语义, 已经不能中参数类型中, 直接用匿名函数来表示参数的类型了;
这里还有一个方式, 就是用Trait的方式, 也可以做到func as arg type:
trait FunctionCaller {
fncall_function &self, function: &Fn(u8) -> bool) -> bool;
}
struct MyFunctionCaller {
data: u8,
}
impl FunctionCaller for MyFunctionCaller {
fncall_function &self, function: &Fn(u8) -> bool) -> bool {
function(self.data)
}
}
fnmain ) {
let my_function_caller = &MyFunctionCaller{data: 8};
println!("{}", invoke(my_function_caller));
}
fninvoke function_caller: &FunctionCaller) -> bool {
let max = 5;
let closure = &move |arg: u8| { arg < max };
function_caller.call_function(closure)
}