学习rust函数,就需要从范式的角度学习,rust参照的范式有函数式、泛型、面向对象,这里的面向对象并非存粹的面向对象。
rust函数式范式
函数本身是一种类型
fn main() {
let func: IncType = inc;
println!("3 + 1 = {}", func(3));
println!("3 + 1 = {}", inc(3));
}
type IncType = fn(i32) -> i32;
fn inc(n: i32) -> i32 {
n + 1
}
如上例子,inc是一种fn(i32)-> i32的类型,可以赋值将inc赋值给该种类型
函数式中函数可作为返回值,即高阶函数
fn main() {
let func = make_inc();
println!("3 + 1 = {}", func(3));
}
fn make_inc() -> fn(i32) -> i32 {
fn inc(n: i32) -> i32 {
n + 1
}
inc
}
fn math(op: fn(i32, i32) -> i32, a: i32, b: i32) -> i32 {
op(a, b)
}
fn sum(a: i32, b: i32) -> i32 {
a + b
}
fn product(a: i32, b: i32) -> i32 {
a * b
}
fn main() {
let (a, b) = (2, 3);
println!("sum {}", math(sum, a, b));
println!("product {}", math(product, a, b));
}
然后就是函数式的map、filter、fold套件
fn is_odd(n: u32) -> bool {
n % 2 == 1
}
fn main() {
let sum_of_squared_odd_numbers: u32 =
(0..5).map(|n| n * n) // 所有自然数取平方
.filter(|&n| is_odd(n)) // 取奇数
.fold(0, |sum, i| sum + i); // 最后加起来
println!("functional style: {}", sum_of_squared_odd_numbers);
}
面向对象和泛型
rust的面向对象是假的面向对象,基于泛型实现,是一种Ad-hoc的多态,使用泛型实现。但是由于rust的实现都是在静态编译期确定类型,各种类型在编译器也就确定了,是一种类型推导过程,而并非面向对象思想中的运行期间确定多态。
例如:
#[derive(Debug, PartialEq)]
struct Foo(i32);
#[derive(Debug, PartialEq)]
struct Bar(i32, i32);
trait Inst {
fn new(i: i32) -> Self
}
impl Inst for Foo {
fn new(i: i32) -> Foo {
Foo(i)
}
}
impl Inst for Bar {
fn new(i: i32) -> Bar {
Bar(i, i + 10)
}
}
fn foobar<T: Inst>(i: i32) -> T {
T::new(i)
}
fn main() {
let f: Foo = foobar(10);
println!("{}", f);
let b: Bar = Bar(10);
println!("{}", b);
}
小结
rust语言也是参考了多种语言实现,实现了多种范式,抓住这些范式可以减少学习负担。
网友评论