函数在 Rust 代码中非常普遍。我们已经使用过语言中最重要的函数之一:main函数,它是很多程序的入口点。你也见过fn关键字,它用来声明新函数。

Rust 代码中的函数和变量使用 snake case 规范风格。在 snake case 中,所有字母都是小写并使用下划线分隔单词。这是一个包含函数定义示例的程序:

  1. fn main() {
  2. println!("Hello, world!");
  3. another_function();
  4. }
  5. fn another_function() {
  6. println!("Another function.");
  7. }

fn(i32) -> i32 { } 一个接收 i32 类型参数并返回 i32 类型参数的函数。函数也有一种 类型。

函数将一堆指令抽象为具体实体,稍后可以通过其他代码调用这个些指令,并帮助用户管理复杂性。

  1. fn add(a: u64,b: u64) -> u64{
  2. a+b
  3. }
  4. fn main(){
  5. let a: u64 = 17;
  6. let b = 3;
  7. let result = add(a,b);
  8. println!("Result {}",result);
  9. }

在上述代码中,创建了一个名为 add 的新函数。关键字 fn用于创建函数,随后跟着的是函数名 add,圆括号中的ab是参数,花括号中的是函数体。冒号右边是参数的类型。函数的返回类型使用->指定,其后跟着的是类型,即u64。如果函数无返回值,那么可以省略该类型声明。函数也有类型,我们的函数add的类型表示为 fn (u64,u64)->u64。类型声明也可以储存在变量中传递给其他函数。

  1. fn add(x: u64, y: u64) -> u64 {
  2. x + y
  3. }
  4. fn main() {
  5. // 在变量中存储函数类型
  6. let adder: fn(u64, u64) -> u64 = add;
  7. // 将函数作为参数传递给另一个函数
  8. execute(adder, 2, 3);
  9. }
  10. fn execute(f: fn(u64, u64) -> u64, x: u64, y: u64) {
  11. let result = f(x, y);
  12. println!("The result is: {}", result);
  13. }
  • fn (u64, u64) -> u64:这是一个函数类型的表示方式,描述了一个接受两个 u64 类型的参数,并返回一个 u64 类型结果的函数。这种表示方式可以用来定义接受此类函数为参数的函数,或者声明此类型的变量。
  • 你可以将符合这个类型签名的函数赋值给一个变量。例如,如果你有一个名为 add 的函数,它接受两个 u64 类型的参数并返回它们的和(也是 u64 类型),你可以创建一个此类型的变量来引用 add 函数。
  • 仔细查看 add 的函数体,会发现我们不需要像其他语言那样使用关键字 return 来返回 a+b,因为最后一个表达式会自动返回。不过 Rust 中仍有关键字 return,但它用于 提前退出。函数基本上是返回值的表达式,默认情况下是()(Unit)类型的值,这与 C/C++ 中的 void 返回类型相似。也可以在其他函数中声明返回值,这用于你很难将某个函数(例如 foo)中的某个功能作为语句序列进行推断时。在这种情况下,你可以在本地函数 bar 中提取这些行,然后在父函数 foo 中定义它们。

:::info Rust 的类型推断基于 Hindly-Milner 类型系统。该系统 包含一组规则和算法,可以通过编程语言进行类型推 断。其采用了一种有效的类型推断方法,在线性时间 内执行,使它对大型程序的类型检查具有实际意义。

:::

Hindley-Milner(HM)
Hindley-Milner(HM)类型系统是一种自动类型推导算法,最初用于 ML 语言家族。这种类型系统的核心优点是能够在没有显式类型注解的情况下,自动推导出表达式的类型。它得名于两位数学家和逻辑学家:Roger Hindley 和 Robin Milner,他们分别独立发现了这一算法的基础理论。
特点
  • 类型推导:HM 类型系统可以自动推导程序中表达式的类型,减少了编程时需要显式指定类型的情况。
  • 类型多态:支持参数多态(parametric polymorphism),也就是通常所说的泛型编程。这意味着函数可以被定义为对多种类型通用,而不需要针对每个类型重写函数。
  • 类型安全:在编译时进行类型检查,可以避免很多类型错误,提高程序的安全性和可靠性。
  • 无歧义性:每个表达式在给定环境中的类型都是唯一确定的,或者报错说明无法推导出类型。