虽然 rust 与 haskell 相比,并不是真正的函数式编程,但不得不说,还真的有点 haskell 的意思。我们看一个匿名函数:
1. 一个简单的匿名函数
fn main() {
let inc = |x| x + 1;
println!("{}", inc(1))
}
运行一下,结果显示 2,很好吧?
2. 函数是一等公民?
haskell 有一个令人印象很深的特点,就是函数和“变量”没有区别。例如,我们可以定义 inc 函数如下:
inc x = x + 1
够简单吧?
在 haskell 中定义一个恒等于 1 的函数 one,这个函数不需要输入参数 x:
one = 1
我靠,这个与我们熟知的变量没区别吧?因为函数名称和参数之间没有小括号分隔,所以在 haskell 这样“纯正的”函数式编程语言中,函数和变量没区别。用 c 语言模拟一下的话,是这个样子:
int one() {
return 1;
}
当然如果你打算写一个算法,就会发现,c 语言即使不用变量,也成不了函数式编程语言。
在 rust 中,one 有两种实现方法:
let one = 1; //变量
或者,
let one = || 1; //匿名函数
写一段完整的程序看一下:
fn main() {
let one = || 1;
println!("{}", one())
}
这和 c 语言一副德行,无论如何伪装,函数名后面的小括号一下子就暴露身份,就凭这一点,rust 无论如何也成不了函数式程序设计语言。如果说常量、变量是一等公民,那么,函数和他们从表达形式上,还是不一样吧?
3. rust 函数可以当参数赋值?
是的,函数和struct、enum等变量没啥区别,定义完成后,当然可以赋值给变量,也可以作为函数的参数传递。
下面的例子中,匿名函数是不是有一点像 sql 命令,直接嵌入到我们的代码里面了。这意味着即使我们开发的代码库已经编译提交,用户还是有可能在用我们的函数库的时候把自己的算法嵌入进来。
use std::ops::*;
fn proc(x: i32, do_something: fn(x: i32) -> i32) -> i32 {
return do_something(x);
}
fn main() {
let a = proc(123, |x| x + 1);
println!("{}", a);
let a = proc(123, |x| x * 10);
println!("{}", a);
let a = proc(123, |x| x*x + 10*x +3);
println!("{}", a);
}
当然也不一定非得用匿名函数,正常的函数也一样工作:
fn proc(x: i32, do_something: fn(x: i32) -> i32) -> i32 {
return do_something(x);
}
fn myfun(x: i32) -> i32 {
return x + 1;
}
fn main() {
let a = proc(123, myfun);
println!("{}", a);
}
这个 myfun 和普通变量没啥区别吧?
4. rust 的函数和 c 语言的函数指针有啥区别?
抛开 rust 语法机制的优势,本质没啥区别,都是过程式程序设计的代码空间的地址指针,这个与 haskell 中的函数概念有本质的不同。在我们陶醉于 rust 匿名函数、函数可做参数的种种优势时,c 语言的回调函数已经存在几十年了!
原创不易,如有帮助,敬请关注、点赞、收藏,谢谢支持!