Rust语言入门第六篇-函数

文章目录

  • Rust 函数
    • 函数
    • 函数(方法)讲解
      • 1.什么是函数(方法)
      • 2.方法(函数的构成)
        • 1. 什么是形参
        • 2.什么是实参
        • 3.定义方法(函数)类型
          • (方法)函数类型
        • 5.方法(函数)的 return
          • 使用 `return` 关键字
          • 隐式返回
        • 5.关联方法,自由函数
          • 关联方法(Associated Methods)
          • 自由函数(Free Functions)
    • 技术细节
      • 带有返回值的方法
      • 不带返回值的方法

Rust 函数

函数

在大部分语言中函数或者叫方法,函数(方法)在大多数语言中是不可缺少的,因此到处可见,所以函数(方法)是什么呢?
在 Rust 中,函数被也可以称为方法(methods),它们是 Rust 程序中的基本构建块之一。方法是一段被命名并可重复调用的代码块,用于执行特定的任务。方法可以接受参数并返回值,它们通常用于执行特定的操作或完成特定的计算。

你说得对,让我更具体一些。在 Rust 中,函数和方法有一些区别:

  1. 函数(Functions):在 Rust 中,函数是一段独立的代码块,可以接受参数并返回值,但它们不附属于任何特定的类型。函数可以在任何地方被调用,它们通常用于执行一些独立的操作,而不依赖于特定的数据结构或类型。

  2. 方法(Methods):方法是与特定类型相关联的函数。它们通过"self"参数(或"&self"、"&mut self"等)来访问其所属的类型的数据。在 Rust 中,方法的调用通常使用"对象.方法名()"的语法,其中对象是方法所属的类型的实例。方法的定义通常在特定类型的实现块(impl block)中。

在 Rust 中,尤其是在处理结构体或枚举类型时,很多代码确实会写在方法里面,这样可以更好地组织和管理代码,并使代码更具有结构性和可读性。

达标的 Rust 方法应该满足以下要求:

  1. 与类型相关联:方法应该与特定类型相关联,并通过"self"参数来访问该类型的数据。

  2. 遵循所有函数的要求:方法也必须遵循函数的所有要求,包括安全性、性能、可读性和健壮性。

  3. 符合面向对象的原则:方法的设计应该符合面向对象编程的原则,即将操作和数据封装在一起,提供一种清晰的接口供用户使用。

下面是一个简单的 Rust 方法的结构组成,包括可选的修饰符:

// 可选的修饰符:pub 等
fn 方法名(&self, 参数1: 参数类型, 参数2: 参数类型, ...) -> 返回类型 {// 执行语句...// 可选的返回值return 返回值;
}

让我们来解释一下每个部分:

  1. fn: 这个关键字用于声明一个函数。

  2. 方法名: 函数的名称,你可以根据需要为函数起一个合适的名字。

  3. (&self): 这个是函数的第一个参数,表示方法是一个对象的方法。self 表示当前对象的引用,& 表示这是一个不可变引用,如果需要修改对象,可以使用 &mut self

  4. 参数1: 参数类型, 参数2: 参数类型, ...: 这是函数的参数列表,每个参数都有一个名称和一个类型。

  5. -> 返回类型: 这是函数的返回类型,表示函数执行完毕后将返回的值的类型。

  6. {}: 函数体由一对大括号包围,里面包含了函数的具体实现。

  7. // 执行语句: 这是函数内部的执行语句,你可以在这里编写任何你想要执行的代码逻辑。

  8. return 返回值;: 这是一个可选项,用于指定函数的返回值。你可以使用 return 关键字来显式地返回一个值,也可以省略返回值,这样函数将会返回一个空的元组 ()

可选的修饰符 pub 可以用于标记函数或其他项为公共的,这样它们就可以被外部模块访问。

函数(方法)讲解

1.什么是函数(方法)

简单理解方法(函数)可以理解为一个载体,好比我是一名优秀的博客作家【方法,函数】,博客作家只是我的代号【方法名,函数名】,并不能代表我的能编写很好的文章,因此就需要我们在方法(函数中进行完善一些行为)这些行为定义了我写博客的过程,这个过程就是我要编写代码的处理行为亦或是我的内在【方法内部的代码】

2.方法(函数的构成)

  1. fn: 这个关键字用于声明一个函数。

  2. 方法名: 函数的名称,你可以根据需要为函数起一个合适的名字。

  3. (&self): 这个是函数的第一个参数,表示方法是一个对象的方法。self 表示当前对象的引用,& 表示这是一个不可变引用,如果需要修改对象,可以使用 &mut self

  4. 参数1: 参数类型, 参数2: 参数类型, ...: 这是函数的参数列表,每个参数都有一个名称和一个类型。

  5. -> 返回类型: 这是函数的返回类型,表示函数执行完毕后将返回的值的类型。

  6. {}: 函数体由一对大括号包围,里面包含了函数的具体实现。

  7. // 执行语句: 这是函数内部的执行语句,你可以在这里编写任何你想要执行的代码逻辑。

  8. return 返回值;: 这是一个可选项,用于指定函数的返回值。你可以使用 return 关键字来显式地返回一个值,也可以省略返回值,这样函数将会返回一个空的元组 ()

1. 什么是形参

在 Rust 中,方法的形参(formal parameters)指的是方法定义中声明的参数,用于接收调用该方法时传入的值。形参位于方法签名的括号内,在括号内以逗号分隔,每个形参都由参数名和参数类型组成。

下面是一个简单的示例,展示了一个具有两个形参的方法的定义:

struct Rectangle {width: u32,height: u32,
}impl Rectangle {// 方法定义,这里的`&self`是一个形参,表示该方法可以通过引用调用,并且该引用是不可变的// 方法的第二个形参`increase_by`是一个u32类型的参数,用于指定增加的值fn increase_size(&mut self, increase_by: u32) {self.width += increase_by;self.height += increase_by;}
}fn main() {let mut rect = Rectangle {width: 10,height: 20,};println!("Before increase: width = {}, height = {}", rect.width, rect.height);// 调用`increase_size`方法,并传入一个值作为`increase_by`形参rect.increase_size(5);println!("After increase: width = {}, height = {}", rect.width, rect.height);
}

在上面的示例中,increase_size方法有两个形参:&mut selfincrease_by。其中,&mut self 表示方法的接收者是一个可变引用,并且这是一个隐式参数,它不需要在调用方法时显式传入。而 increase_by 则是方法的第二个形参,它是一个 u32 类型的参数,用于指定增加的值。

形参在方法的定义中起到了接收外部传入值的作用,允许方法在执行时操作这些值,并根据需要进行计算或处理。

2.什么是实参

在 Rust 中,实参(actual parameters)是指在调用函数或方法时传递给它们的具体值或表达式。实参是实际被传递给函数或方法的数据,在调用过程中用于填充函数或方法的形参。

以下是一个简单示例,演示了如何在 Rust 中使用实参来调用函数和方法:

// 定义一个函数,接受两个参数,并打印它们的和
fn add_numbers(a: i32, b: i32) {println!("The sum of {} and {} is: {}", a, b, a + b);
}struct Rectangle {width: u32,height: u32,
}impl Rectangle {// 方法定义,接受一个额外的参数,并将该参数添加到宽度和高度上fn increase_size(&mut self, increase_by: u32) {self.width += increase_by;self.height += increase_by;}
}fn main() {// 调用函数`add_numbers`,并传入两个实参:3 和 5add_numbers(3, 5);let mut rect = Rectangle {width: 10,height: 20,};println!("Before increase: width = {}, height = {}", rect.width, rect.height);// 调用`increase_size`方法,并传入一个实参作为`increase_by`参数rect.increase_size(5);println!("After increase: width = {}, height = {}", rect.width, rect.height);
}

在上面的示例中,add_numbers函数被调用时,传递了两个实参:3 和 5。这两个实参填充了函数定义中的形参 ab。同样地,在调用 increase_size 方法时,传递了一个实参 5,它填充了方法定义中的 increase_by 形参。

实参提供了函数和方法执行所需的具体数据,允许程序根据需要操作或处理这些数据。

3.定义方法(函数)类型

在 Rust 中,方法和函数都可以被视为类型,这些类型主要与它们的签名(signature)相关。方法类型(Method Type)和函数类型(Function Type)可以被用作变量的类型、函数的参数类型或返回类型等。

(方法)函数类型

函数类型表示一个函数的签名,它是用来定义方法(函数)所要返回的是什么类型。在 Rust 中,函数类型可以使用 fn 关键字定义。例如,具有参数类型为 i32i32,返回类型为 i32 的函数类型可以写成 fn(i32, i32) -> i32

fn add(a: i32, b: i32) -> i32 {a + b
}fn main() {let func: fn(i32, i32) -> i32 = add;println!("Result: {}", func(3, 5));
}

在上面的示例中,add 函数的类型是 fn(i32, i32) -> i32,并且可以将其赋值给变量 func,因为它们的类型匹配。

5.方法(函数)的 return

在 Rust 中,方法(以及函数)可以使用 return 关键字来提前返回值,也可以通过简单地将要返回的表达式放在函数体的最后来隐式返回值。

使用 return 关键字

在 Rust 中,你可以使用 return 关键字来显式地提前返回值。这在你想要在函数的中间部分返回结果,并且不希望继续执行函数的余下部分时很有用。

fn is_even(num: i32) -> bool {if num % 2 == 0 {return true;}false // 这一行也可以省略,因为最后一个表达式会被隐式返回
}fn main() {println!("Is 5 even? {}", is_even(5)); // 输出:Is 5 even? false
}

在上面的示例中,如果 num 是偶数,is_even 函数会提前返回 true,否则会返回 falsereturn 关键字可以在任何地方使用,即使在代码块中。

隐式返回

在 Rust 中,函数和方法的最后一个表达式会被隐式地作为返回值。这意味着你不需要使用 return 关键字来返回值,只需要将要返回的值放在函数体的最后即可。

fn is_even(num: i32) -> bool {num % 2 == 0 // 这是最后一个表达式,会被隐式返回
}fn main() {println!("Is 5 even? {}", is_even(5)); // 输出:Is 5 even? false
}

在上面的示例中,is_even 函数的最后一个表达式是 num % 2 == 0,因此它会被隐式地作为返回值。

无论是使用 return 关键字还是隐式返回,都可以有效地返回值,但根据个人偏好和代码清晰度,你可以选择其中之一。通常来说,如果函数或方法比较简单,且只有一个返回点,那么使用隐式返回可能更清晰。

5.关联方法,自由函数

在 Rust 中,方法(Methods)可以分为两种类型:关联方法(Associated Methods)和自由函数(Free Functions)。其中,关联方法是绑定到结构体、枚举或 trait 的方法,而自由函数则是没有绑定到特定类型的函数。

关联方法(Associated Methods)

关联方法是绑定到类型上的方法,它们使用 impl 块在类型的上下文中定义。关联方法没有类型限制,因为它们直接与类型相关联。

struct Rectangle {width: u32,height: u32,
}impl Rectangle {// 这是一个关联方法fn new(width: u32, height: u32) -> Rectangle {Rectangle { width, height }}
}fn main() {let rect = Rectangle::new(10, 20); // 调用关联方法
}

在上面的例子中,new 是一个关联方法,因为它使用 impl 块与 Rectangle 类型相关联。这个方法不接受任何类型的参数,因为它不需要一个特定的实例来调用。

自由函数(Free Functions)

自由函数是不绑定到类型的函数。它们不在 impl 块中定义,而是直接在模块中定义。

// 这是一个自由函数
fn add(a: i32, b: i32) -> i32 {a + b
}fn main() {let result = add(3, 5); // 调用自由函数println!("Result: {}", result);
}

在这个例子中,add 是一个自由函数,因为它不与任何特定的类型相关联。

总的来说,在 Rust 中,无论是关联方法还是自由函数,它们都是类型无关的。不像一些其他语言,如面向对象语言中的方法,它们必须与特定的类或对象相关联。

技术细节

在 Rust 中,方法和函数都是严格的类型安全的,并且方法始终与其接收者的类型相关联。

另外,Rust 中的函数和方法都可以有返回值。即使函数或方法不返回任何值,它们也会隐式返回 (),即 unit 类型,表示一个空的元组。这种情况下,你可以说函数或方法的返回值为空。

下面分别展示 Rust 中带有返回值的方法和不带返回值的方法的示例:

带有返回值的方法

struct Rectangle {width: u32,height: u32,
}impl Rectangle {// 这是一个带有返回值的方法fn area(&self) -> u32 {self.width * self.height}
}fn main() {let rect = Rectangle { width: 10, height: 20 };let area = rect.area(); // 调用带有返回值的方法println!("Area: {}", area); // 输出:Area: 200
}

在上面的示例中,area 是一个带有返回值的方法,它返回 u32 类型的矩形的面积。

不带返回值的方法

struct Counter {count: u32,
}impl Counter {// 这是一个不带返回值的方法fn increment(&mut self) {self.count += 1;}
}fn main() {let mut counter = Counter { count: 0 };counter.increment(); // 调用不带返回值的方法println!("Count: {}", counter.count); // 输出:Count: 1
}

在这个示例中,increment 是一个不带返回值的方法。它对 Counter 结构体的 count 字段进行增量操作,但不返回任何值。

总之,Rust 中的方法和函数都可以有返回值,即使函数或方法不返回任何值,它们也会隐式返回 ()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/821864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何用JAVA如何实现Word、Excel、PPT在线前端预览编辑的功能?

背景 随着信息化的发展,在线办公也日益成为了企业办公和个人学习不可或缺的一部分,作为微软Office的三大组成部分:Word、Excel和PPT也广泛应用于各种在线办公场景,但是由于浏览器限制及微软Office的不开源等特性,导致…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之十二 简单人脸识别

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之十二 简单人脸识别 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之十二 简单人脸识别 一、简单介绍 二、简单人脸识别实现原理 三、简单人脸识别案例实现简…

数据密集型应用系统设计 PDF 电子书(Martin Kleppmann 著)

简介 《数据密集型应用系统设计》全书分为三大部分: 第一部分,主要讨论有关增强数据密集型应用系统所需的若干基本原则。首先开篇第 1 章即瞄准目标:可靠性、可扩展性与可维护性,如何认识这些问题以及如何达成目标。第 2 章我们比…

MongoDB的安装配置及使用

文章目录 前言一、MongoDB的下载、安装、配置二、检验MongoDB是否安装成功三、Navicat 操作MongoDB四、创建一个集合,存放三个文档总结 前言 本文内容: 💫 MongoDB的下载、安装、配置 💫 检验MongoDB是否安装成功 ❤️ Navicat 操…

RHCE1

一.在系统中设定延迟任务要求如下 在系统中建立easylee用户,设定其密码为easylee 延迟任务由root用户建立 要求在5小时后备份系统中的用户信息文件到/backup中 确保延迟任务是使用非交互模式建立 确保系统中只有root用户和easylee用户可以执行延迟任务的设定 [root…

【单例模式】饿汉式、懒汉式、静态内部类--简单例子

单例模式是⼀个单例类在任何情况下都只存在⼀个实例,构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例,对外提供⼀个静态公有⽅法获取实例。 目录 一、单例模式 饿汉式 静态内部类 懒汉式 反射可以破坏单例 道高一尺魔高一丈 枚举 一、单例…

[html]一个动态js倒计时小组件

先看效果 代码 <style>.alert-sec-circle {stroke-dasharray: 735;transition: stroke-dashoffset 1s linear;} </style><div style"width: 110px; height: 110px; float: left;"><svg style"width:110px;height:110px;"><cir…

【GD32】_时钟架构及系统时钟频率配置

文章目录 一、有关时钟源二、系统时钟架构三、时钟树分析四、修改参数步骤1、设置外部晶振2、选择外部时钟源。3、 设置系统主频率大小4、修改PLL分频倍频系数 学习系统时钟架构和时钟树&#xff0c;验证及学习笔记如下&#xff0c;如有错误&#xff0c;欢迎指正。主要记录了总…

力扣152. 乘积最大子数组

Problem: 152. 乘积最大子数组 文章目录 题目描述思路复杂度Code 题目描述 思路 1.初始化&#xff1a;首先&#xff0c;我们创建两个数组maxNum和minNum&#xff0c;并将它们初始化为输入数组nums。这两个数组用于存储到当前位置的最大和最小乘积。我们还需要一个变量maxProduc…

c#数据储存栈(stack)和堆(heap)的方式

C#中&#xff0c;类的数据存储是通过堆&#xff08;Heap&#xff09;和栈&#xff08;Stack&#xff09;这两种内存结构来实现的。理解这两种数据结构的工作方式有助于更好地理解C#中的数据存储机制。 栈&#xff08;Stack&#xff09; 栈是一种后进先出&#xff08;Last In,…

Python医院挂号脚本

创建一个简单的医院挂号系统通常涉及患者注册、挂号功能&#xff0c;以及医生的安排。这里我们将使用 Python 来实现一个基本的命令行挂号系统。我们将构建以下功能&#xff1a; 患者注册&#xff1a;输入患者基本信息&#xff0c;注册后保存患者信息。挂号服务&#xff1a;根…

python 一个点运算符操作的字典库:DottedDict

DottedDict 是一种特殊的数据结构&#xff0c;它结合了字典&#xff08;Dictionary&#xff09;和点符号&#xff08;Dot Notation&#xff09;访问的优点&#xff0c;为用户提供了一种更加直观和方便的方式来处理和访问嵌套的数据。在这篇文章中&#xff0c;我们将深入探讨 Do…

Java复习第二十天学习笔记(过滤器Filter),附有道云笔记链接

【有道云笔记】二十 4.8 过滤器Filter https://note.youdao.com/s/dSofip3f 一、为什么要使用过滤器 项目开发中&#xff0c;经常会用到重复代码的实现。 1、请求每个servlet都要设置编码 2、判断用户是否登录&#xff0c;只有登录了才有操作权限。 二、过滤器相关Api int…

从汇编代码理解数组越界访问漏洞

数组越界访问漏洞是 C/C 语言中常见的缺陷&#xff0c;它发生在程序尝试访问数组元素时未正确验证索引是否在有效范围内。通常情况下&#xff0c;数组的索引从0开始&#xff0c;到数组长度减1结束。如果程序尝试访问小于0或大于等于数组长度的索引位置&#xff0c;就会导致数组…

.Net ajax 接收参数

后端部分代码 一般处理程序 public void ProcessRequest(HttpContext context){context.Response.ContentType "text/plain";string str_index context.Request.Form.AllKeys.Contains("index") ? context.Request.Form["index"].ToString(…

windows关闭Windows Search功能

我发现windows最恶心的功能就是自动更新和搜索。自动更新就是个毒瘤&#xff0c;得到了全世界的人讨厌。 而搜索功能难用、慢和造成卡死&#xff0c;根本没有存在的必要。并且他的windows search filter服务会在每次移动大量文件后建立索引&#xff0c;持续的占用cpu和硬盘的资…

常用的Java线程阻塞业务方法

在Java中常常使用到多线程处理一些业务&#xff0c;但是也会遇到多线程处理时带来的业务逻辑时序不对问题&#xff0c;例如需要等待一个业务处理完或者下一步的逻辑需要等待多线程得到的结果&#xff0c;下面是几种常用的方法 使用 Thread.join() 方法 对于已知的线程列表&…

python解释器安装路径查询以及版本查询

查询安装路径 1、利用脚本&#xff1a; 路径: import sys import osprint(当前 Python 解释器路径&#xff1a;) print(sys.executable)运行结果&#xff1a; 目录: print(当前 Python 解释器目录&#xff1a;) print(os.path.dirname(sys.executable))运行结果&#xff1a…

static+单例模式+类的复合继承

汇编语言 汇编语言是最靠谱的验证“编程语言相关知识点”正确性的方式 汇编语言与机器语言一一对应&#xff0c;每一条机器语言都有与之对应的汇编指令 机器语言是计算机使用的语言&#xff0c;它是一串二进制数字 汇编语言可以通过汇编得到机器语言机器语言可以通过反汇编得到…

设计模式—门面模式

定义: 门面模式,也称为外观模式&#xff0c;是一种结构型设计模式。它的主要目的是提供统一的接口来访问子系统中的多个接口&#xff0c;从而简化客户端与复杂子系统之间的交互。 在门面模式中&#xff0c;一个门面类充当中介&#xff0c;为客户端提供一个简化了的访问方式&…