IT技术之家

首页 > 编程

编程

Rust函数_rust 感叹号_小飞学习与分享

发布时间:2023-11-28 21:03:00 编程 29次 标签:rust 开发语言
Rust函数简介,包含main函数、发散函数、const函数及递归函数。...

一、简介
Rust的函数使用关键字fn来声明。函数可以有一系列的输入参数,还有一个返回类型。如果函数返回一个值,返回类型必须在箭头 -> 之后指定。函数体包含一系列的语句。函数返回可以使用return语句,也可以使用表达式。

Rust的函数体内也允许定义其他item,包括静态变量、常量、函数、trait、类型、模块等。当你需要一些item仅在此函数内有用的时候,可以把它们直接定义到函数体内,以避免污染外部的命名空间。

以下是简单的代码样例:

// 和 C/C++ 不一样,Rust 的函数定义位置是没有限制的
fn main() {
    // 我们可以在这里使用函数,后面再定义它
    fizzbuzz_to(100);
}

// 一个返回布尔值的函数
fn is_divisible_by(lhs: u32, rhs: u32) -> bool {
    // 边界情况,提前返回
    if rhs == 0 {
        return false;
    }

    // 这是一个表达式,可以不用 `return` 关键字
    lhs % rhs == 0
}

// 一个 “不” 返回值的函数。实际上会返回一个单元类型 `()`。
fn fizzbuzz(n: u32) -> () {
    if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }
}

// 当函数返回 `()` 时,函数签名可以省略返回类型
fn fizzbuzz_to(n: u32) {
    for n in 1..=n {
        fizzbuzz(n);
    }
}

二、发散函数
Rust支持一种特殊的函数,它的返回类型是感叹号!,这种函数叫作发散函数。发散类型的最大特点就是可以被转换为任意一个类型。

在Rust中以下这些情况永远不会返回,它们的类型就是!:

    panic!以及基于它实现的各种函数/宏,比如unimplemented!、unreachable!等。死循环loop{}。进程退出函数std::process::exit以及类似的libc中的exec一类函数。

以下是简单的代码样例:

// 发散函数
fn diverges() -> ! {
    panic!("This function never returns!");
}

fn main() {
    diverges();
}

三、main函数
Rust编写的可执行程序的入口就是fn main()函数。Rust的main函数和其他语言的设计稍微有点不一样,传递参数和返回状态码都由单独的API来完成。如果要读取环境变量,可以用std::env::var()以及std::env::vars()函数获得。进程可以在任何时候调用exit()直接退出,退出时候的错误码由exit()函数的参数指定。

简单的代码样例如下:

fn main() {
    for arg in std::env::args() {
        println!("Arg: {}", arg);
    }
    std::process::exit(0);
}

编译后,执行时携带几个参数:main -opt1 opt2 – opt3,输出结果如下:

四、const函数
函数可以用const关键字修饰,这样的函数可以在编译阶段被编译器执行,返回值也被视为编译期常量。const函数是在编译阶段执行的,因此相比普通函数有许多限制,并非所有的表达式和语句都可以在其中使用。

以下是简单的代码样例:

// const函数
const fn cube(num: usize) -> usize {
    num * num * num
}

fn main() {
    const DIM: usize = cube(2);
    const ARR: [i32; DIM] = [0; DIM];
    println!("{:?}", ARR);
}

五、递归函数
所谓递归调用,指的是函数直接或者间调用自己。下面用经典的Fibonacci数列来举例:

fn fib(index: u32) -> u64 {
    if index == 1 || index == 2 {
        1
    } else {
        fib(index - 1) + fib(index - 2)
    }
}
fn main() {
    let f8 = fib(8);
    println!("{}", f8);
}