函数

概述

函数在 Rust 语言中是普遍存在的。

格式

fn <函数名> ( <参数 参数名:数据类型> ) -> <返回值> { 
<函数体>
<返回值> // 注意不能有分号
}

其中 Rust 函数名称的命名风格是小写字母以下划线分割;

基本知识

对于一些重复执行的代码,可以将其定义成一个函数,方便调用。 函数 = 函数签名 + 函数体 按值传递的参数使用 mut 关键字

fn modify(mut v: Vec<u32>) -> Vec<u32> {
    v.push(42);
    v
}
fn main() {
    let v = vec![1, 2, 3];
    let v = modify(v);
    println!("v = {:?}", v);
}

按引用传递参数时的 mut 的用法

fn modify(v: &mut Vec<u32>) {
    v.push(42);
}
fn main() {
    let mut v = vec![1, 2, 3];
    modify(&mut v);
    println!("v = {:?}", v);
}

函数屏蔽

变量屏蔽(variable shadow):当声明变量绑定后,如果再次声明同名的变量绑定,则之前的变量绑定会被屏蔽。 函数不能多次定义:否则报错 error[E0428]: the name xxx is defined multiple times。 但是,可以通过显式地使用花括号将同名的函数分割到不同的作用域中。默认的函数定义只在当前作用域内有效,会屏蔽作用域外的同名函数。

fn f() {
    println!("1");
}
fn main() {
    f(); // 2
    {
        f(); // 3
        fn f() {
            println!("3");
        }
    }
    f(); // 2
    fn f() {
        println!("2");
    }
}

函数参数模式匹配

函数中的参数等价于一个隐式的 let 绑定,而 let 绑定本事是一个模式匹配的行为。所以函数参数也支持模式匹配。

#[derive(Debug)]
struct S {
    i: i32,
}
fn f(ref s: S) {
    println!("{:p}", s); // 需要 ref 修饰
    println!("{:?}", s);
}
fn main() {
    let s = S { i: 42 };
    f(s);
    // println!("{:?}", s);
}

函数返回值

Rust 中的函数只能有唯一的返回值。

没有返回值的情况,实际上相当于返回了一个单元值 ()。如果有多个返回值,可以使用元组类型来返回。

fn foo(x: isize, y: isize) -> (isize, isize) {
    (x + y, x - y)            // 可以使用 return 来返回。也可以不加分号,默认返回。
}
fn main() {
    let (a, b) = foo(5, 8);
    println!("a = {}, b = {}", a, b);  // a = 13, b = -3
}

泛型函数

通用类型支持。

use std::ops::Mul;
fn square<T: Mul<T, Output = T>>(x: T, y: T) -> T {
    x * y
}
fn main() {
    // println!("square(3, 6) = {}", square(3, 6)); // square(3, 6) = 18
    let a = square(37.2, 41.1); // f64
    let b = square::<u32>(10, 6); // 若使用 u32,则参数不能是负数,不能是浮点数
    let c = square::<f32>(16f32, 26.3); // 指定 f32 类型
}

Last updated