坏蛋Dan
知乎@坏蛋Dan
发布时间:2024.1.3

前言

昨天我们学习了rust的基础数据类型

坏蛋Dan:rust基础学习--day5

今天我们接着往下


函数(functions)

函数的用法和其他语言差不多,都是函数名()

函数的创建也和其它语言差不多

fnrust中定义函数的关键字。

整体格式为fn 函数名小写_多个词用下划线分隔 (参数A: 参数A类型, 参数B: 参数B类型) -> 函数返回值的类型 { ... }

其中函数参数的类型是必须要有的,而函数返回值的类型可以没有,毕竟函数可能没有返回值,默认为unit也就是上篇文章中说的空元组()

函数作用域

函数的作用域和别的语言也是一样的,同级作用域可相互调用,外层作用域的函数可以被内层调用,而内层作用域的函数无法被外层调用(并不是都是这样,还是有办法去调用的,这里只说默认情况)。

rust中也是一个{}之间为一个作用域。


是不是和别的语言差不多?

但其实rust中的函数还有一些自己的特点。

语句(statement)和表达式(expression)

如果你学过babel[3],或者看过了解过ast(抽象语法树)。那么你应该看到过各种type: xxxExpression或者type: xxxStatement,这些就是语句和表达式(来自于你写的代码),不过是以树的形式表现出来。

表达式是语句的一部分,比如println!("test")这就是一个表达式,在babel中会变成callxxxExpression可以简单的理解为是函数调用表达式。

rust中,语句是没有返回值的,比如

c语言中这样是可行的,但是rust中行不通,因为let y = 6是一个语句,他用了关键字let,当然,就算没用lety = 6也是一条语句。

那什么是表达式呢?在rust中会对代码做判断,如果某个代码或者某几个代码计算出来是一个值,并且和别的代码组成了一个语句,那么这个就是一个表达式。比如1 + 2或者等号右边的一个1,就是一个表达式。

另外rust将大括号以及大括号内的东西定义为一个表达式,所以你可以写下面这种代码

但前面说过,表达式是语句的一部分,所以其实很难去区分这俩。

所以rust中就根据这个问题提供了一种方式去定义是语句还是表达式,比如上边中c大括号内a()没有带上;这个符号,那么这个a()执行的结果就会被判断为是一个表达式并返回给c。所以说rust是对;敏感的语言,不像js中,只有在IIFE前才必须加上; 其他写不写无所谓,浏览器会自动补上。

扯远了,回到代码中,如果c变量右边表达式a()带上;那么就会被判断是一个语句,这个块作用域也就没有返回值。


函数返回值

通过上边那个c变量赋值语句你应该已经知道了一个块作用域的返回值是根据最后一行代码是否带;来判断的,如果最后一行带上了;这说明这是一个语句,意味着这个块作用域没有返回值,会返回默认的()空元组。

另外你应该也看出来了,rust中没有return这个关键字。

而函数主体可不就是一个块作用域吗,所以上面的逻辑完全适用于函数。

最后需要注意的一点就是,如果你的函数有返回值,那么就必须写上返回值的type,定义方式最开始说了在()后面带上 -> type


总结

rust中函数和其他语言还是有很大不同的,尤其是以最后一行作为返回值(还需要判断是否带了;)这个点。

参考

  1. ^rust-functions https://doc.rust-lang.org/book/ch03-03-how-functions-work.html#functions
  2. ^rust-functions-statement-and-expression https://doc.rust-lang.org/book/ch03-03-how-functions-work.html#statements-and-expressions
  3. ^babel https://babeljs.io/docs/en/usage
  4. ^rust-function-return-value https://doc.rust-lang.org/book/ch03-03-how-functions-work.html#functions-with-return-values

发布于 2022-11-29 16:04・IP 属地广东