参数与返回值 #

一、参数传递方式 #

1.1 值传递 #

默认情况下,参数按值传递:

mojo
fn modify_value(x: Int):
    x = x + 1

def main():
    var num = 10
    modify_value(num)
    print(num)

main()

1.2 引用传递 (inout) #

使用 inout 关键字传递可变引用:

mojo
fn modify_value(inout x: Int):
    x = x + 1

def main():
    var num = 10
    modify_value(num)
    print(num)

main()

1.3 只读引用 (ref) #

使用 ref 传递只读引用:

mojo
fn print_length(ref s: String):
    print(len(s))

def main():
    let text = "Hello, Mojo!"
    print_length(text)

main()

1.4 所有权转移 (owned) #

使用 owned 转移参数所有权:

mojo
fn take_ownership(owned s: String):
    print(s)

def main():
    let text = "Hello"
    take_ownership(text)

main()

二、参数约束 #

2.1 类型约束 #

mojo
fn process[T: Numeric](a: T, b: T) -> T:
    return a + b

def main():
    print(process(1, 2))
    print(process(1.5, 2.5))

main()

2.2 多重约束 #

mojo
trait Addable:
    fn __add__(self, other: Self) -> Self

fn add[T: Addable](a: T, b: T) -> T:
    return a + b

def main():
    print(add(1, 2))

main()

2.3 默认值约束 #

mojo
fn create_array(size: Int, value: Int = 0) -> List[Int]:
    var arr: List[Int] = []
    for _ in range(size):
        arr.append(value)
    return arr

def main():
    print(create_array(5))
    print(create_array(5, 10))

main()

三、可变参数 #

3.1 位置可变参数 #

mojo
fn sum_all(*values: Int) -> Int:
    var total = 0
    for v in values:
        total += v
    return total

def main():
    print(sum_all(1, 2, 3, 4, 5))

main()

3.2 关键字可变参数 #

mojo
fn create_dict(**kwargs: String) -> Dict[String, String]:
    var result: Dict[String, String] = {}
    for key, value in kwargs.items():
        result[key] = value
    return result

def main():
    let d = create_dict(name="Alice", city="Beijing")
    print(d)

main()

3.3 混合参数 #

mojo
fn mixed_params(required: Int, *args: Int, **kwargs: String):
    print(f"Required: {required}")
    print(f"Args: {args}")
    print(f"Kwargs: {kwargs}")

def main():
    mixed_params(1, 2, 3, 4, name="Alice", city="Beijing")

main()

四、返回值高级特性 #

4.1 多返回值 #

mojo
fn min_max(numbers: List[Int]) -> (Int, Int):
    var min_val = numbers[0]
    var max_val = numbers[0]
    
    for num in numbers:
        if num < min_val:
            min_val = num
        if num > max_val:
            max_val = num
    
    return min_val, max_val

def main():
    let nums = [3, 1, 4, 1, 5, 9, 2, 6]
    let minimum, maximum = min_max(nums)
    print(f"Min: {minimum}, Max: {maximum}")

main()

4.2 命名返回值 #

mojo
struct Result:
    var value: Int
    var error: String

fn divide(a: Int, b: Int) -> Result:
    if b == 0:
        return Result(0, "Division by zero")
    return Result(a // b, "")

def main():
    let result = divide(10, 2)
    if result.error == "":
        print(result.value)
    else:
        print(result.error)

main()

4.3 Option类型 #

mojo
fn find_element(arr: List[Int], target: Int) -> Optional[Int]:
    for i in range(len(arr)):
        if arr[i] == target:
            return i
    return None

def main():
    let nums = [1, 2, 3, 4, 5]
    let index = find_element(nums, 3)
    
    if index is not None:
        print(f"Found at index: {index}")
    else:
        print("Not found")

main()

4.4 Result类型 #

mojo
fn parse_int(s: String) -> Result[Int, String]:
    try:
        return Ok(Int(s))
    except:
        return Err("Invalid integer")

def main():
    let result = parse_int("42")
    
    match result:
        case Ok(value):
            print(value)
        case Err(error):
            print(error)

main()

五、泛型函数 #

5.1 泛型参数 #

mojo
fn identity[T](x: T) -> T:
    return x

def main():
    print(identity(42))
    print(identity("Hello"))

main()

5.2 泛型约束 #

mojo
trait Comparable:
    fn __lt__(self, other: Self) -> Bool

fn min[T: Comparable](a: T, b: T) -> T:
    if a < b:
        return a
    return b

def main():
    print(min(1, 2))
    print(min("apple", "banana"))

main()

5.3 多泛型参数 #

mojo
fn pair[T, U](first: T, second: U) -> (T, U):
    return first, second

def main():
    let p = pair(1, "Hello")
    print(p)

main()

六、函数指针 #

6.1 函数类型 #

mojo
alias IntOp = fn(Int, Int) -> Int

fn apply_op(a: Int, b: Int, op: IntOp) -> Int:
    return op(a, b)

fn add(a: Int, b: Int) -> Int:
    return a + b

fn multiply(a: Int, b: Int) -> Int:
    return a * b

def main():
    print(apply_op(5, 3, add))
    print(apply_op(5, 3, multiply))

main()

6.2 函数指针数组 #

mojo
fn add(a: Int, b: Int) -> Int: return a + b
fn sub(a: Int, b: Int) -> Int: return a - b
fn mul(a: Int, b: Int) -> Int: return a * b
fn div(a: Int, b: Int) -> Int: return a // b

def main():
    let operations: List[fn(Int, Int) -> Int] = [add, sub, mul, div]
    let names = ["+", "-", "*", "/"]
    
    for i in range(4):
        let result = operations[i](10, 5)
        print(f"10 {names[i]} 5 = {result}")

main()

七、闭包 #

7.1 基本闭包 #

mojo
def main():
    let x = 10
    
    let closure = lambda y: x + y
    
    print(closure(5))

main()

7.2 捕获变量 #

mojo
def main():
    var counter = 0
    
    let increment = lambda:
        counter += 1
        return counter
    
    print(increment())
    print(increment())
    print(increment())

main()

7.3 闭包作为参数 #

mojo
fn apply_to_each(arr: List[Int], f: fn(Int) -> Int) -> List[Int]:
    var result: List[Int] = []
    for num in arr:
        result.append(f(num))
    return result

def main():
    let numbers = [1, 2, 3, 4, 5]
    let doubled = apply_to_each(numbers, lambda x: x * 2)
    print(doubled)

main()

八、参数最佳实践 #

8.1 使用不可变参数 #

mojo
fn process(data: List[Int]):
    for item in data:
        print(item)

def main():
    let numbers = [1, 2, 3]
    process(numbers)

main()

8.2 避免过多参数 #

mojo
struct Config:
    var host: String
    var port: Int
    var timeout: Int

fn connect(config: Config):
    print(f"Connecting to {config.host}:{config.port}")

def main():
    let cfg = Config("localhost", 8080, 30)
    connect(cfg)

main()

8.3 使用Option处理可选参数 #

mojo
fn greet(name: String, title: Optional[String] = None):
    match title:
        case Some(t):
            print(f"Hello, {t} {name}")
        case None:
            print(f"Hello, {name}")

def main():
    greet("Alice")
    greet("Bob", Some("Dr."))

main()

九、总结 #

本章学习了:

  • 值传递与引用传递
  • inout、ref、owned关键字
  • 可变参数处理
  • 多返回值
  • Option和Result类型
  • 泛型函数
  • 函数指针
  • 闭包

下一章,我们将学习结构体基础。

最后更新:2026-03-27