rustlings_函数

本文介绍了Rust编程中的函数基础知识,包括函数的构成、参数类型、函数调用及返回值的处理。通过一系列练习,探讨了如何定义和使用函数,以及解决函数调用中遇到的问题。特别提到了main函数的特性,强调了函数在程序设计中的重要性和资源消耗。此外,还讨论了形参和实参的区别,并提及了函数参数传递的规则。
摘要由CSDN通过智能技术生成

前言

函数

在这里,你将会学到如何实现一个函数,同时了解rust的编译器是如何按图索骥。

更进一步的信息

练习一

提示

我们的main函数在试图调用另一个函数,但是它找不到另一个函数。它觉得这个函数应该叫做call_me,它期待这个函数没有参数也不返回值。这听起来很像main函数不是吗?

题解

从这个练习开始,题目一下子变得有些让人摸不到头脑。不得不承认,这一套题只是一套题而已,它的提示并没有打算让你先学一下,然后再做做看,而是把题目摆在你的面前,然后告诉你,请你来试试看。

函数是rust的一等公民,但是其实对于新手来说函数是什么是个很难去思考的问题,毕竟如果是第一次就碰到这个概念的人,函数就是一个名为函数的东西而已,但是对于我这样的学了一点点java的人而言,函数也是个非常非常难以思考的东西,因为在java里面,本质上都是对象,函数也只是类或者对象的函数而已。客观孤立的函数让人感到有些苦恼。

既然在这里开始了函数,那么我们就得先解决一个第一章变量里面一直熟视无睹的问题,main函数。就像是java或者c之类的一样(纯新可以无视这句),首先main函数是由至少四部分组成的:

//fn是一个函数的关键字,告诉编译器,接下来的内容是一个函数。
fn main() {
//上方的这个main,是一个特殊的标识,从函数的角度来说,这是函数的名字,从rust的角度,这是整个程序的起点
    
    //从这里开始,是函数的行为,也就是这个函数需要干什么,它的用处是什么,称为函数体
}

一个函数必须要实现这些内容,否则的话就不能称为一个函数了,或者说,它就不能通过编译。所以对于这道题来说,依样画葫芦把 main 函数的main换成call_me就能解决问题。当然这里要说一个可能只学过大学c语言的同学可能会怀疑的问题,函数的位置有讲究吗?我不知道使用python会不会有同样的问题,因为没接触过,但是在rust里面,函数的位置并不会对程序的运行产生影响,rust的编译器会很好的去找到函数的位置并对函数进行执行。这里要说明一个定义类名的写法,rust的标准是使用 word_is_like_this这个样子用下划线分割函数名当中不同单词的,在一个函数名由多个单词组成的时候,函数名就会比实际表意的内容拉的很长,有人喜欢有人不喜欢,但是rust的建议还是希望大家可以遵守。

当然对于main函数我还有一些想说的,那就题目走到哪里我聊到哪里吧。

练习二

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1hkE7NoH-1622127157164)(https://pic.finnewworld.top/img/2021/05/24/p9emkt.png)]

提示

对于带参函数,rust要求所有的参数标识都显式地说明该参数的类型,但是call_me没有写明参数的类型。

题解

这里其实是在完整整个函数的功能,在上一题,我说到函数是rust的一等公民,那么显然不会随随便便地设计。函数的设计目的在于:1. 实现具体功能.2. 实现数据操作和传递。函数的存在原因,是因为过去很多古老的语言,会把所有的代码集中在同一个很大的运行程序中,这一方面保证了代码高效的逐行运行,减少内存与存储的压力,这对于当时极其有限的存储和计算能力来说极为重要,但也导致很严重的问题,没有人知道这个代码是用来做什么的,也没人知道该怎么修改。

在存储与内存还有计算能力提升之后,用函数把代码隔离开来显然成为了银弹,这个可以有效同时自由地分割并让人理解的功能,迅速被所有编程语言所支持。

所以函数是消耗资源的,而非自然而然的存在的,只不过消耗的资源可以完全忽视。

对于这道题来说,其实是一个如何定义我想要传入函数的参数是什么样的参数的问题。在第一章变量里面,我们知道了如果我们要定义一个变量,我们要这样做:let [mut] [name]:[type] = [value];这个练习在解决的问题就是函数如何传递数据,我们可以看到题目上已经有的内容是[name]:在这个层面上来说,rust的语句还是挺统一的,[mame]:[type]。所以这道题直接增补一下函数的类型即可。

然后我想说一下形参和实参的问题,这两样东西在rust中有非常复杂的发展,但是我在这个地方只说最简单的东西。对于形参来说,它对自己所在的函数,是一个实际存在的东西,和在函数体内写对于函数内部来说是一样的。但是对于外部来说,函数的传参是特殊的,因为只有这些具有被传参意义的内容能够被传入,也必须传入对应的内容。其他内容之后会一点点的出现。

最后这道题里面要讨论的问题就是,其实main函数是可以有参数的,同时也是可以被传参的。我以前从来没有考虑过这个问题,直到我看了cs100,在很开始的地方,这个给我的是一种震惊,在java里面的main函数里面其实一直暗示着它可以传参,但是我一直视而不见。

这个内容似乎有点多,我额外再写一篇文章吧。于是我写完了,在这里,我自己一边学一边尝试一边写的,估计非常的繁琐,但是希望新手了解代码要怎么尝试着去看,而不是看着main函数完全无法下手。

*在火车上,就先写到这里啦,祝大家生活愉快

练习三

提示

这次,函数的声明写的没有问题,但是在我们的调用操作哪里有些问题。

题解

既然缺了变量类型,那么就加上即可

练习四

// 商店正在促销,价格是偶数的时候,减10元,如果是奇数,那么减3块
fn main() {
    let original_price = 51;
    println!("Your sale price is {}", sale_price(original_price));
}

fn sale_price(price: i32) -> {
    if is_even(price) {
        price - 10
    } else {
        price - 3
    }
}

提示

错误信息指出,第十四行希望在->后面返回一个类型,在这个位置我们会告知编译器函数理应返回什么类型————可以看看is even函数怎么写的!

题解

函数返回值的问题其实就是个格式,可以直接看我后面写的答案,不过我这边想要说明的一点就是,rust这个函数写法其实挺麻烦的,—>这个符号不是那么的顺手,以前我打字-和=经常会打串,各位可能需要自己适应一下这个问题。

练习五

提示

这是个非常非常常见的手误,去掉一个符号就能解决。
这个报错源于rust对描述和声明的判断方式:描述返回一个根据运算得到的值,而声明简单的返回一个()类型,这个()类型会和c系语言中void函数表达相似的行为。
当我们想要从square函数里返回一个i32类型的变量,但它会返回一个类似于()的一个类型,它们并不同。
有两种解决方法,在num * num;前加上return,或者是删去num * num后的;`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值