Rust - 函数

Rust中通过 fn 关键字来声明某个函数。

针对函数名,Rust使用snake case命名规范,即所有的字母都是小写的,单词之间使用下划线分开。

fn main() {
    println!("Hello, world!");
    another_function(); //函数调用
}

fn another_function() {
    println!("Another function.");
}

(一)函数的参数

我们还可以定义拥有 参数 的函数,参数是一种特殊变量,是函数签名的一部分。

函数签名:函数签名是一组能唯一标识一个函数的特定信息,通常包括函数名、参数类型和参数个数

当函数拥有参数(形参)时,可以通过为这些参数提供具体值(实参)的方式,让函数得到想要的信息。

在这版 another_function 中,我们增加了一个参数:

fn main() {
    another_function(5); //实参为5
}

fn another_function(x: i32) {  
    //形参为x,接受类型为i32
    println!("The value of x is: {x}");
}

在Rust中,必须 声明每个参数的类型。

这是 Rust 设计中的一个特性:要求在函数定义中提供类型注解,意味着编译器再也不需要在函数代码中进行自动推断了。而且,在知道函数需要什么类型后,编译器就能够给出更有用的错误消息。

当定义多个参数时,需使用逗号分隔,像这样:

fn main() {
    print_labeled_measurement(5, 'h');
}

fn print_labeled_measurement(value: i32, unit_label: char) {
    println!("The measurement is: {value}{unit_label}");
}

(二)语句和表达式

函数体由一系列的语句和一个可选的结尾表达式构成。但目前为止,我们见到的函数还不包含结尾表达式。

Rust 是一门基于表达式(expression-based)的语言,这是一个不同于其他语言的重要区别。所以让我们看看语句与表达式有什么区别以及这些区别是如何影响函数体的。

语句 是执行一些操作但不返回值的指令。 表达式 是会计算并产生一个值。让我们看一些例子。

fn main() {
    let y = 6;
}

在上面这个例子中,哪些是语句,哪些是表达式?因为语句是执行一些操作但不返回值的指令,所以第二行代码是语句,除第二行之外的函数定义也是语句,整体来看,上面整个例子本身就是一个语句。

而表达式则是会计算出一个值,并且大部分 Rust 代码是由表达式组成的。

考虑一个数学运算,比如 5 + 6,这是一个表达式并计算出值 11。表达式可以是语句的一部分,就像在语句 let y = 6; 中, 6 是一个表达式,它计算出的值是 6。

所以会产生一个值的就是表达式,不管这个值是什么,为不为空。以此为考虑,可以判断出函数调用是一个表达式。宏调用是一个表达式。用大括号创建的一个新的块作用域也是一个表达式,例如:

fn main() {
    let y = {
        let x = 3;
        x + 1
    };

    println!("The value of y is: {y}");
}

上面这个表达式需要进行说明一下,特别是第2到5行。

{
    let x = 3;
    x + 1
}

如上所示,这是一个代码块,并且它的值是 4,同时这个值会作为 let 语句的一部分最终被绑定到 y 上。

为什么?注意 x+1 这一行在结尾没有分号,与我们所见过的大部分代码行不同。

在Rust中,表达式的求值结果是它最后一个操作符的结果。在这个例子中,x + 1是一个加法表达式,它的结果是4。

如果一个表达式后面没有分号,那么它会被隐式地返回。所以在这个例子中,这句表达式刚好位于代码块(花括号括起来的区域)的最后一行,所以“4”会被隐式地返回并赋值给变量y。

(三)函数的返回值

函数可以向调用它的代码返回值。在进行函数声明时,我们要在箭头(->)后声明返回值的具体类型,但是不可以对它进行命名。

在 Rust 中,函数的返回值就是函数体最后一个表达式的值。

虽然也可以使用 return 关键字和指定值,并可从函数中提前返回;但大部分函数都是隐式的返回最后的表达式。

这是一个有返回值的函数的例子:

fn five() -> i32 {
    5
}

fn main() {
    let x = five();

    println!("The value of x is: {x}");
}
//结果:The value of x is: 5

在 five 函数中没有函数调用、宏、甚至没有 let 语句 —— 只有数字 5。这在 Rust 中是一个完全有效的函数。注意,five函数中也指定了函数返回值的类型,就是 -> i32。

这段代码有两个重要的部分:首先,let x = five(); 这一行表明我们使用函数的返回值初始化一个变量。因为 five 函数返回 5,所以此时这一行的代码含义与如下代码相同:

let x = 5;

其次,five 函数在声明时没有参数,而且定义了返回值类型,不过函数体中只有单单一个 5 也没有分号。但因为这是一个表达式,我们可以将它当做返回值进行返回。

另一个例子同理:

fn main() {
    let x = plus_one(5);

    println!("The value of x is: {x}");
}

fn plus_one(x: i32) -> i32 {
    x + 1
}
//结果:The value of x is: 6

但如果在 x + 1 的表达式后面加上一个分号,把它从表达式变成语句,我们就会看到报错。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值