Carbon函数定义 #

一、函数概述 #

函数是组织代码的基本单元,用于封装可重用的代码块。Carbon使用 fn 关键字定义函数。

二、基本函数 #

2.1 函数定义 #

carbon
fn Greet() {
  Print("Hello, Carbon!");
}

Greet();

2.2 带参数的函数 #

carbon
fn Greet(name: String) {
  Print("Hello, {0}!", name);
}

Greet("World");

2.3 带返回值的函数 #

carbon
fn Add(a: i32, b: i32) -> i32 {
  return a + b;
}

var result: i32 = Add(10, 20);
Print("{0}", result);

2.4 多返回值 #

carbon
fn Divide(a: i32, b: i32) -> (i32, bool) {
  if (b == 0) {
    return (0, false);
  }
  return (a / b, true);
}

var (quotient, success) = Divide(10, 2);
if (success) {
  Print("结果: {0}", quotient);
}

三、参数 #

3.1 位置参数 #

carbon
fn Add(a: i32, b: i32) -> i32 {
  return a + b;
}

Add(1, 2);

3.2 默认参数 #

carbon
fn Greet(name: String, greeting: String = "Hello") {
  Print("{0}, {1}!", greeting, name);
}

Greet("World");           // Hello, World!
Greet("World", "Hi");     // Hi, World!

3.3 命名参数 #

carbon
fn CreatePoint(x: f64, y: f64, z: f64 = 0.0) -> Point {
  return Point(x, y, z);
}

CreatePoint(x = 1.0, y = 2.0);
CreatePoint(y = 2.0, x = 1.0);
CreatePoint(x = 1.0, y = 2.0, z = 3.0);

3.4 可变参数 #

carbon
fn Sum(values: i32...) -> i32 {
  var total: i32 = 0;
  for (v in values) {
    total += v;
  }
  return total;
}

Sum(1, 2, 3, 4, 5);  // 15
Sum(10, 20);         // 30

3.5 引用参数 #

carbon
fn Swap(a: i32&, b: i32&) {
  var temp: i32 = a;
  a = b;
  b = temp;
}

var x: i32 = 10;
var y: i32 = 20;
Swap(x, y);
Print("x={0}, y={1}", x, y);  // x=20, y=10

四、返回值 #

4.1 显式返回 #

carbon
fn Max(a: i32, b: i32) -> i32 {
  if (a > b) {
    return a;
  }
  return b;
}

4.2 隐式返回 #

carbon
fn Add(a: i32, b: i32) -> i32 {
  a + b  // 最后一个表达式作为返回值
}

4.3 无返回值 #

carbon
fn Log(message: String) {
  Print("[LOG] {0}", message);
  // 无返回值(或返回 ())
}

4.4 返回类型推断 #

carbon
fn Add(a: i32, b: i32) -> auto {
  return a + b;  // 推断为 i32
}

五、函数类型 #

5.1 函数指针 #

carbon
typealias BinaryOp = fn (i32, i32) -> i32;

fn Add(a: i32, b: i32) -> i32 { return a + b; }
fn Subtract(a: i32, b: i32) -> i32 { return a - b; }

fn Apply(op: BinaryOp, a: i32, b: i32) -> i32 {
  return op(a, b);
}

Apply(Add, 10, 5);      // 15
Apply(Subtract, 10, 5); // 5

5.2 函数作为参数 #

carbon
fn Process(data: [i32], transform: fn (i32) -> i32) -> [i32] {
  var result: [i32] = ();
  for (item in data) {
    result.Push(transform(item));
  }
  return result;
}

var numbers: [i32; 5] = (1, 2, 3, 4, 5);
var doubled: [i32] = Process(numbers, fn (x: i32) -> i32 { return x * 2; });

5.3 函数作为返回值 #

carbon
fn GetOperation(op: String) -> fn (i32, i32) -> i32 {
  match (op) {
    case "add" => fn (a: i32, b: i32) -> i32 { return a + b; };
    case "sub" => fn (a: i32, b: i32) -> i32 { return a - b; };
    case "mul" => fn (a: i32, b: i32) -> i32 { return a * b; };
    default => fn (a: i32, b: i32) -> i32 { return 0; };
  }
}

var add_fn: auto = GetOperation("add");
Print("{0}", add_fn(10, 5));  // 15

六、匿名函数与Lambda #

6.1 Lambda表达式 #

carbon
// 简单lambda
var add = fn (a: i32, b: i32) -> i32 { return a + b; };
Print("{0}", add(1, 2));

// 简化语法
var double = fn (x: i32) -> i32 { x * 2 };
Print("{0}", double(5));  // 10

6.2 闭包 #

闭包可以捕获外部变量:

carbon
fn MakeCounter() -> fn () -> i32 {
  var count: i32 = 0;
  return fn () -> i32 {
    count += 1;
    return count;
  };
}

var counter = MakeCounter();
Print("{0}", counter());  // 1
Print("{0}", counter());  // 2
Print("{0}", counter());  // 3

6.3 捕获方式 #

carbon
fn Example() {
  var x: i32 = 10;
  var y: i32 = 20;
  
  // 值捕获
  var by_value = fn () -> i32 { return x; };
  
  // 引用捕获
  var by_ref = fn () -> i32 { 
    y += 1;
    return y; 
  };
  
  Print("{0}", by_value());  // 10
  Print("{0}", by_ref());    // 21
  Print("{0}", y);           // 21
}

七、函数重载 #

7.1 基本重载 #

carbon
fn Add(a: i32, b: i32) -> i32 {
  return a + b;
}

fn Add(a: f64, b: f64) -> f64 {
  return a + b;
}

fn Add(a: String, b: String) -> String {
  return a + b;
}

Add(1, 2);         // i32版本
Add(1.5, 2.5);     // f64版本
Add("Hello, ", "World");  // String版本

7.2 参数数量重载 #

carbon
fn Add(a: i32) -> i32 {
  return a;
}

fn Add(a: i32, b: i32) -> i32 {
  return a + b;
}

fn Add(a: i32, b: i32, c: i32) -> i32 {
  return a + b + c;
}

八、泛型函数 #

8.1 类型参数 #

carbon
fn Max[T:! Compare](a: T, b: T) -> T {
  return if a > b then a else b;
}

Max(10, 20);       // i32
Max(3.14, 2.71);   // f64
Max("a", "b");     // String

8.2 约束 #

carbon
interface Numeric {
  fn Add(me, other: me) -> me;
}

fn Sum[T:! Numeric](values: [T]) -> T {
  var total: T = T.Zero;
  for (v in values) {
    total = total.Add(v);
  }
  return total;
}

8.3 多类型参数 #

carbon
fn Pair[T, U](first: T, second: U) -> (T, U) {
  return (first, second);
}

var p = Pair(1, "hello");  // (i32, String)

九、内联函数 #

9.1 内联定义 #

carbon
inline fn Square(x: i32) -> i32 {
  return x * x;
}

// 编译时会展开为 x * x
var result: i32 = Square(5);

9.2 内联优势 #

carbon
// 内联适合小型、频繁调用的函数
inline fn Min(a: i32, b: i32) -> i32 {
  return if a < b then a else b;
}

// 避免函数调用开销
for (i in 0..1000000) {
  var m = Min(i, 500000);
}

十、递归函数 #

10.1 基本递归 #

carbon
fn Factorial(n: i32) -> i32 {
  if (n <= 1) {
    return 1;
  }
  return n * Factorial(n - 1);
}

Print("{0}", Factorial(5));  // 120

10.2 尾递归 #

carbon
fn FactorialTail(n: i32, acc: i32 = 1) -> i32 {
  if (n <= 1) {
    return acc;
  }
  return FactorialTail(n - 1, n * acc);
}

Print("{0}", FactorialTail(5));  // 120

10.3 斐波那契 #

carbon
fn Fibonacci(n: i32) -> i32 {
  if (n <= 1) {
    return n;
  }
  return Fibonacci(n - 1) + Fibonacci(n - 2);
}

Print("{0}", Fibonacci(10));  // 55

十一、高阶函数 #

11.1 Map #

carbon
fn Map[T, U](arr: [T], f: fn (T) -> U) -> [U] {
  var result: [U] = ();
  for (item in arr) {
    result.Push(f(item));
  }
  return result;
}

var numbers: [i32; 5] = (1, 2, 3, 4, 5);
var squared: [i32] = Map(numbers, fn (x: i32) -> i32 { return x * x; });

11.2 Filter #

carbon
fn Filter[T](arr: [T], pred: fn (T) -> bool) -> [T] {
  var result: [T] = ();
  for (item in arr) {
    if (pred(item)) {
      result.Push(item);
    }
  }
  return result;
}

var numbers: [i32; 10] = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
var evens: [i32] = Filter(numbers, fn (x: i32) -> bool { return x % 2 == 0; });

11.3 Reduce #

carbon
fn Reduce[T, U](arr: [T], init: U, f: fn (U, T) -> U) -> U {
  var result: U = init;
  for (item in arr) {
    result = f(result, item);
  }
  return result;
}

var numbers: [i32; 5] = (1, 2, 3, 4, 5);
var sum: i32 = Reduce(numbers, 0, fn (a: i32, b: i32) -> i32 { return a + b; });

十二、最佳实践 #

12.1 单一职责 #

carbon
// 好的做法:每个函数做一件事
fn ValidateEmail(email: String) -> bool {
  return email.Contains("@");
}

fn ValidatePassword(password: String) -> bool {
  return password.Length() >= 8;
}

fn ValidateUser(email: String, password: String) -> bool {
  return ValidateEmail(email) and ValidatePassword(password);
}

12.2 函数长度 #

carbon
// 好的做法:函数简短
fn CalculateTotal(items: [Item]) -> f64 {
  var subtotal: f64 = CalculateSubtotal(items);
  var discount: f64 = CalculateDiscount(subtotal);
  var tax: f64 = CalculateTax(subtotal);
  return subtotal - discount + tax;
}

12.3 有意义的命名 #

carbon
// 好的命名
fn FindUserById(id: i32) -> Optional(User);
fn IsEmailValid(email: String) -> bool;
fn CalculateTotalPrice(items: [Item]) -> f64;

// 避免的命名
fn Find(i: i32) -> Optional(User);
fn Check(s: String) -> bool;
fn Calc(arr: [Item]) -> f64;

十三、总结 #

本章我们学习了:

  1. 函数定义:fn关键字、参数、返回值
  2. 参数类型:位置参数、默认参数、命名参数、可变参数
  3. 返回值:显式返回、隐式返回、多返回值
  4. 函数类型:函数指针、函数作为参数和返回值
  5. 匿名函数:Lambda表达式、闭包
  6. 函数重载:参数类型和数量重载
  7. 泛型函数:类型参数、约束
  8. 高阶函数:Map、Filter、Reduce

接下来让我们学习Carbon的复合类型!

最后更新:2026-03-27