Rust学习笔记-4-基础篇:函数

前言

本文主要梳理Rust函数相关的知识点。

定义

  • Rust的函数使用关键字fn开头
  • 函数返回 可以使用return语句,也可以使用表达式。
  • Rust 代码中的函数和变量名使用 snake case 规范风格。在 snake case 中,所有字母都是小写并使用下划线分隔单词。
    fn main() {
        println!("Hello, world!");
    
        another_function();
    }
    
    fn another_function() {
        println!("Another function.");
    }
  • Rust 中的函数定义以 fn 开始并在函数名后跟一对圆括号。大括号告诉编译器哪里是函数体的开始和结尾。
  • 上例中,another_function的定义处在调用点之后。Rust 不关心函数定义于何处,只要定义了就行。
  • 函数可以拥有参数parameters),是函数签名的一部分;当函数拥有参数(形参)时,可以为这些参数提供具体的值(实参)。技术上讲,这些具体值被称为参数(arguments)。实际交流中不用这么麻烦,统称参数。
  • 在函数签名中,必须 声明每个参数的类型。这是 Rust 设计中一个经过慎重考虑的决定。
  • 函数可以有返回值。返回值不用命名,但要在箭头(->)后声明它的类型。在 Rust 中,函数的返回值等同于函数体最后一个表达式的值。使用 return 关键字和指定值,可从函数中提前返回;但大部分函数隐式的返回最后的表达式。以下是一个示例:
    fn five() -> i32 {
        5
    }
    
    fn main() {
        let x = five();
    
        println!("The value of x is: {}", x);
    }
    
  •  函数也可以不写返回类型,在这种情况下,编译器会认为返回类型 是unit()。

  • 函数也可以赋值给变量,然后调用这个变量。如下示例。

    fn add1(t : (i32,i32)) -> i32 {    t.0 + t.1 }
    fn add2((x,y) : (i32,i32)) -> i32 {    x + y }
    
    fn main() {   
        let p = (1, 3);
        // func 是一个局部变量    
        let func = add2;    
        // func 可以被当成普通函数一样被调用
        println!("evaluation output {}", func(p)); 
    }
    
  •  在Rust中,每一个函数都具有自己单独的类型,但是这个类型可以转换到fn类型函数。示例如下。不过,在参数、 返回值类型不同的情况下是不能作类型转换的。

    fn add1(t : (i32,i32)) -> i32 {    t.0 + t.1 }
    fn add2((x,y) : (i32,i32)) -> i32 {    x + y }
    
    fn main() {        
        // 先让 func 指向 add1   
        let mut func = add1;   
        // 再重新赋值,让 func 指向 add2   
        func = add2;  //直接赋值,编译会报错。
    }
    
    //修正方式如下
    // 写法一,用 as 类型转换 
    let mut func = add1 as fn((i32,i32))->i32; 
    // 写法二,用显式类型标记 
    let mut func : fn((i32,i32))->i32 = add1;
    
  •  Rust的函数体内也允许定义其他item,包括 静态变量、常量、函数、trait、类型、模块等。

发散函数

  • Rust支持一种特殊的发散函数(Diverging functions),它的返回类 型是感叹号!。发散类型的最大特点就是,它可以被转换为任意一个类型。
    fn diverges() -> ! {   
     panic!("This function never returns!"); 
    }
    
    //发散函数可以被转换成任意类型
    let x : i32 = diverges(); 
    let y : String = diverges();
    
  •  在Rust中,有这些情况永远不会返回,它们的类型就是!,它们是:1,panic!以及基于它实现的各种函数/宏,比如unimplemented!、 unreachable!;2,无限循环loop{}; ·3,进程退出函数std::process::exit以及类似的libc中的exec一类函数。

main函数

直接上个示例。

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

此前,Rust的main函数只支持无参数、无返回值类型的声明方式。后来Rust设计组扩展了main函数的签名, 使它变成了一个泛型函数,这个函数的返回类型可以是任何一个满足 Terminationtrait约束的类型,其中()、bool、Result都是满足这个约束 的,它们都可以作为main函数的返回类型。

const fn函数

  • 函数可以用const关键字修饰,这样的函数可以在编译阶段被编译器 执行,返回值也被视为编译期常量。

函数的递归调用

  • “当前版本的Rust暂时还不支持尾递归优化,因此如果递归调 用层次太多的话,是有可能撑爆栈空间的” 。

注:后续查证一下看rust的当前版是否之尾递归优化。列为TODO。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值