likes
comments
collection
share

从前端到rust:如何在rust中使用函数

作者站长头像
站长
· 阅读数 10

函数声明

聊完了rust中基本数据类型之后,我们先来看看rust中的函数。

rust中的函数声明也比较简单:

fn say_sth(sth: String ) ->(){
   println!("i said, {}!", sth);
}

从上面这段代码中我们可以看到,rust中用fn关键字在表示函数声明,这点和js类型,不同的是js中的关键字是function。fn后面的say_sth的函数名,后面跟小括号来表示函数的入参,->表示后面跟着的是函数的返回值,这里的返回值是单元类型(还记得吗,上一篇文章中讲的),之后的大括号里面的则是函数体,函数具体的执行逻辑就写在函数体里面。

函数的参数

之前我们在奖变量声明的时候提到过,rust的在变量声明的时候可以自由选择标注或者不标注变量类型,但是在函数声明的时候,rust则要求开发则必须显式的声明函数的参数类型。道理很简单,你在声明变量的时候可以通过变量的值来推断出变量的类型,但是在函数声明的时候,因为你的参数是依赖函数调用的时候传值,如果你不显式的声明参数的类型,那么rust就无法知道这个函数的参数类型是什么。

习惯了js的同学,在声明函数的时候记得一定要标识出函数的每一个参数的具体类型。当然忘记了也没关系,因为ide或者编译的时候都会有错误提示~。

但是,作为一个合格的开发者,基本的语法还是要记住的。

函数参数的类型声明也很简单,就是冒号后面跟上具体的参数类型,例如:

fn add_person(name: String, age:i8 ){
   println!("add person,name:{}, age:{}!", name, age);
}

函数体

函数体就是你写在花括号里面的内容,函数的执行逻辑就写在函数体里面。

要了解函数体之前我们先要讲解两个概念:一个是执行语句;一个是表达式。执行语句就是一行完成的函数语句,以分号结尾,而表达式则是执行语句的一部分。例如:

let x = 8 + 4;

上面这行代码就是一行完整的执行语句,8+4就是表达式。再例如:

let x = 8;

8也是表达式。

一般在js里面(其实其他语言也一样),我们不会重点去讲执行语句和表达式,但是在rust中,情况略微有些不同,因为rust中的表达式会默认将值返回。

什么意思呢?

我们看下面的例子:

fn add_number(a:i32,b:i32) -> i32 {
    a+b
}

注意,下面这段文字很重要,请仔细阅读:

首先,上面函数体里面的a+b没有分号;其次,我们显示的声明了函数的返回值是32位有符号整型,但是我们没有用return返回任何东西。但是,上面这个方法却是符合rust语法要求的。

为什么呢?

聪明的同学肯定已经想到,这就是rust表达式的作用。在rust中你可以单独使用表达式,方法就是在语句后面不加分号,但是你只能用在函数体的最后一行。其次,rust会默认将表达式的值返回。 因此上面这段代码就等同于:

fn add_number(a:i32,b:i32) -> i32 {
    return a+b;
}

是不是有点意思? 但是更有意思的还在后面,请看:

fn add_number(a: i32, b: i32) -> i32 {
    a + { b * b }
}

上面代码和下面的代码执行效果相同。

fn add_number(a: i32, b: i32) -> i32 {
  return  a + b * b 
}

但是这是为什么呢?

我们首先看,a + { b * b }部分,后面没有分号,所以显然这是一个表达式,整个执行的结果会被返回。但是{ b * b }又是什么意思呢?

我们单独看{ b * b }部分,会发现他和函数体的结构相同,都是花括号后面跟上了执行语句或者表达式,再看bb后面没有分号,所以显然这是一个表达式,那么根据函数体的讲解,这里显然就是把bb的内容返回。再看a + { b * b },那么我们就可以猜测,这里是把b*b的结果和a相加之后返回。

运行结果看,果然也是这样的。

而之所以代码可以这样写,就是因为rust运行我们在函数体里面包裹函数体(其实,js里面也可以,只是我们很少这样写),当然这时候我们叫函数体就不太适合了,或者我们可以叫它执行体,或者执行块(如果有人知道这块有更学术性的名称,可以在评论区告诉我,这里只是我个人的叫法,其实难免有误人之嫌)。

返回值

讲解完函数体之后,我们再来看看返回值。

rust中其实允许我们不声明返回值,就像下面:

fn say_sth(sth: String ){
   println!("i said, {}!", sth);
}

那么这时候,返回值其实默认就是(),即单元类型,这点和js中有相似,默认就是返回undefined。

但是如果在函数中用return显示的返回了一个值或者语句最后是表达式,但是却又没有声明返回值,那么你rust就会告诉你,这段代码存在问题。

返回值的声明方式就是->后面跟具体的类型,注意,->中间不能有空格

函数的调用

fn add_number(a: i32, b: i32) -> i32 {
  return  a + b * b 
}
let x = add_number(6,8);

函数的调用方式和js没什么区别,就是函数名加上你要参入的参数即可。我想应该无需在赘述了。

在rust中,你可以在函数声明前就先调用它,例如:

fn main() {
    add_number(5, 4);
    fn add_number(a: i32, b: i32) -> i32 {
        a + { b * b }
    }
}

这点和js其实也是类似的。

另外再补充一句,如果你有认真阅读本文,其实不难发现,我们在声明函数的时候,函数名统一用的是蛇形命名法,即:用下划线分割单词。这是rust推荐的语言规范,如果你不这样,虽然不会报错,但是会得到编译器的警告。


在讲解完变量、数据类型和函数之后,枯燥的语法课就暂时先告一段落吧,接下来,我们会尝试用rust实现一些小功能,来加深我们对rust语法相关知识点理解。

燥起来吧,Rustaceans.