定义与调用 (Definition & Invocation)

函数定义 (Function Definition)

使用 fn 关键字定义一个函数。其基本语法结构如下:

pub? (comptime|async|...)? fn function_name(parameter*) ReturnType? clause? block

示例:

-- 简单的加法函数
fn add(a: i32, b: i32) -> i32 {
    a + b -- 函数体最后是表达式,隐式返回其值
}

-- 无返回值的函数
pub fn print_greeting(name: String) { -- 等同于 -> void
    println("Hello, {}!", name);
}

-- print_value: for<T:- Display> fn(T)
fn print_value(value: T) where T:- Display {
    println("Value: {}", value);
}

函数调用 (Function Invocation)

调用函数使用函数名,后跟圆括号 (),括号内提供实际参数(也称为实参,arguments)。

let sum = add(5, 3); -- 调用 add 函数,传递 5 和 3 作为参数
print_greeting("Flurry".to_string()); -- 调用 print_greeting

-- 调用泛型函数时,编译时参数可能需要显式提供或由编译器推断
-- print_value<i32>(10);
print_value(10); -- 编译器通常可以推断 T 为 i32

参数传递的规则取决于函数签名中参数的类型(详见 参数详解)。

方法 (Methods)

函数也可以直接关联到某个类型(如 struct, enum, union, mod)上。定义在类型内部的函数称为关联函数

定义:

关联函数直接在类型定义的 {} 内部使用 fn 定义。

struct Point {
    x: f64,
    y: f64,

    pub fn origin() -> Self { -- Self 是当前类型的别名
        Point { .x 0.0, .y 0.0 }
    }

    -- 通常称为“方法”
    pub fn distance_from_origin(*self) -> f64 {
        -- self 指向调用该方法的实例
        math.sqrt(self.x * self.x + self.y * self.y)
    }

    -- 接收可变引用的方法
    pub fn translate(*self, dx: f64, dy: f64) {
        self.x += dx;
        self.y += dy;
    }

     -- 接收所有权的方法
    -- pub fn consume(self) { {- ... -} }
}

调用:

let p1 = Point.origin(); -- 调用静态方法 origin
let p2 = Point { .x 3.0, .y 4.0 }

let dist = p2.distance_from_origin(); -- 调用实例方法 distance_from_origin
println("Distance: {}", dist);       -- 输出: Distance: 5.0

let p3 = Point.origin();
p3.translate(1.0, 2.0); -- 调用可变实例方法 translate
println("Translated: ({}, {})", p3.x, p3.y); -- 输出: Translated: (1.0, 2.0)

方法调用 instance.method(args...) 通常是 TypeName.method(instance.ref, args...)等形式的语法糖。

实现块 (impl) 中的方法:

除了直接在类型定义中,也可以在单独的 impl TypeName { ... }impl TraitName for TypeName { ... } 块中为类型定义函数、子成员等。

struct Counter { value: i32 }

-- 在 impl 块中为 Counter 添加方法
impl Counter {
    fn new() -> Self { Counter { .value 0 } }
    fn increment(*self) { self.value += 1; }
    fn get(*self) -> i32 { self.value }
}

test {
    let c = Counter.new();
    c.increment();
    println("Count: {}", c.get()); -- 输出: Count: 1
}

这种方式有助于将类型的定义和其行为实现分开