当前位置: 首页 > news >正文

Rust-函数

简介

Rust的函数使用关键字fn开头。
函数可以有一系列的输入参数,还有一个返回类型。

函数体包含一系列的语句(或者表达式)。

函数返回可以使用return语句,也可以使用表达式。

Rust编写的可执行程序的入口就是fn main()函数。

以下是一个函数的示例:

在这里插入图片描述
函数体内部是一个表达式,这个表达式的值就是函数的返回值。也可以写returnx+y;这样的语句作为返回值,效果是一样的。

函数也可以不写返回类型,在这种情况下,编译器会认为返回类型是unit()。此处和表达式的规定是一致的。

函数可以当成头等公民(first class value)被复制到一个值中,这个值可以像函数一样被调用。示例如下:

在这里插入图片描述
会出现编译错误。
在这里插入图片描述
虽然add1和add2有同样的参数类型和同样的返回值类型,但它们是不同类型,所以这里报错了。修复方案是让func的类型为通用的fn类型即可:

在这里插入图片描述我们不能在参数、返回值类型不同的情况下作类型转换,比如:
在这里插入图片描述这里再加了一个add3函数,它接受两个i32参数,这就跟add1和add2有了本质区别。

add1和add2是一个参数,类型是tuple包含两个i32成员,而add3是两个i32参数。

三者完全不一样,它们之间是无法进行类型转换的。

另外需要提示的就是,Rust的函数体内也允许定义其他item,包括静态变量、常量、函数、trait、类型、模块等。比如:
在这里插入图片描述

发散函数

Rust支持一种特殊的发散函数(Diverging functions),它的返回类型是感叹号!。如果一个函数根本就不能正常返回,那么它可以这样写:

在这里插入图片描述
因为panic!会直接导致栈展开,所以这个函数调用后面的代码都不会继续执行,它的返回类型就是一个特殊的!符号,这种函数也叫作发散函数。发散类型的最大特点就是,它可以被转换为任意一个类型。比如:

在这里插入图片描述
我们为什么需要这样的一种返回类型呢?先看下面的例子:
在这里插入图片描述
上面这条语句中包含一个if-else分支结构的表达式。我们知道,对于分支结构的表达式,它的每条分支的类型必须一致。那么这条panic!宏应该生成一个什么类型呢?这就是!类型的作用了。因为它可以与任意类型相容,所以编译器的类型检查才能通过。
在Rust中,有以下这些情况永远不会返回,它们的类型就是!。

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

main函数

在大部分主流操作系统上,一个进程开始执行的时候可以接受一系列的参数,退出的时候也可以返回一个错误码。许多编程语言也因此为main函数设计了参数和返回值类型。

在这里插入图片描述

const fn

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

在这里插入图片描述

相关文章:

  • 玩转 Go 生态|Hertz WebSocket 扩展简析
  • 【Databend】多表联结,你不会还没有掌握吧!
  • 12.2内核空间基于SPI总线的OLED驱动
  • 排序算法-希尔排序
  • Oracle 基本命令
  • P1125 [NOIP2008 提高组] 笨小猴——C++
  • Redis面试题14
  • Android Canvas图层saveLayer剪切clipPath原图addCircle绘制对应圆形区域并放大,Kotlin(3)
  • 8. 自定义分页
  • 46 C++ 从主线程向 子线程如何传递参数 ------ join 状态下
  • 关于java继承知识点总结
  • 大语言模型面试问题
  • 备战抖音商城好物年货节,品牌焕发新商机
  • 汽车级线性电压稳压器LM317MBSTT3G:新能源汽车的理想之选
  • Android Studio由于开启代理无法下载依赖,一直在Build model
  • css选择器
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • MaxCompute访问TableStore(OTS) 数据
  • MySQL-事务管理(基础)
  • nodejs实现webservice问题总结
  • Rancher如何对接Ceph-RBD块存储
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • uva 10370 Above Average
  • 闭包--闭包作用之保存(一)
  • 从零搭建Koa2 Server
  • 第2章 网络文档
  • 番外篇1:在Windows环境下安装JDK
  • 构建二叉树进行数值数组的去重及优化
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 我从编程教室毕业
  • 一份游戏开发学习路线
  • 在Docker Swarm上部署Apache Storm:第1部分
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • #Z0458. 树的中心2
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (八)Flask之app.route装饰器函数的参数
  • (理论篇)httpmoudle和httphandler一览
  • (七)Java对象在Hibernate持久化层的状态
  • (转)Mysql的优化设置
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET 材料检测系统崩溃分析
  • .NET/C# 的字符串暂存池
  • .NET基础篇——反射的奥妙
  • .NET连接MongoDB数据库实例教程
  • .net中生成excel后调整宽度