✨✨ 欢迎大家来到景天科技苑✨✨
?? 养成好习惯,先赞后看哦~??
? 作者简介:景天科技苑
?《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
?《博客》:Python全栈,Golang开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。
所属的专栏:Go语言开发零基础到高阶实战
景天的主页:景天科技苑
文章目录
Go语言中的函数1. 什么是函数2. 函数的定义3. 函数的调用4. 常见函数类型1、无参无返回值函数2、无参有返回值函数3、有参有一个返回值函数4、有参有多个返回值函数5、定义函数时给返回值命名 5. 可变参数函数6. 函数的参数传递1、值传递2、引用传递 7. 函数中作用域8. 递归函数递归计算斐波那契数
Go语言中的函数
1. 什么是函数
在Go语言中,函数(Function)是基本的代码块,用于执行特定的任务,并通过输入参数和返回值与外部环境进行交互。
函数是一段具有特殊功能的、可重用的语句组。(将代码封装起来)
特点:可以反复调用,提高代码的复用性,提高开发效率,便于维护管理
go语言中,函数和方法完全是不一样的东西,面向对象里面才有方法
2. 函数的定义
Go语言中,使用func关键字开始,后跟函数名、参数列表(参数名和参数类型)、返回值类型(如果有的话),以及函数体(用大括号{}包围的语句块)。
基本语法如下:
func functionName(parameters) returnType { // 函数体 return returnValue // 可选 }
3. 函数的调用
在Go语言中,函数的调用非常直接,只需要使用函数名加上括号,如果有参数,加上必要的参数即可。如果函数有返回值,可以将返回值赋给变量,或者直接使用(如果不需要处理返回值)。
4. 常见函数类型
1、无参无返回值函数
无返回值函数,不用指定返回值类型
package mainimport "fmt"// 定义函数// 1、无参、没有返回值函数func add() { fmt.Println("计算加法函数")}func main() { add()}
2、无参有返回值函数
// 2、无参数有返回值函数
//需要指定函数返回值类型,并且用return将返回值返回//在调用处用变量接收func add() int { return 3}
3、有参有一个返回值函数
// 有参,有一个返回值函数//指定参数类型,和返回值类型func add(x int, y int) int { return x + y}
4、有参有多个返回值函数
//4、有参,有多个返回值函数//需要指明参数类型,和多个返回值类型,多个返回值返回类型需要用括号括起来//多个返回值用逗号隔开//调用的时候,用多个变量接收返回值func add(x int, y int) (int ,int){ return x + y, y}
给出两个数,得到其中较大者
package mainimport "fmt"func main() { num := max(3, 5) fmt.Println(num)}// 定义比较大小函数func max(x, y int) int { var result int if x > y { result = x } else { result = y } return result}
5、定义函数时给返回值命名
返回多个值,需要括号,需要表明返回值类型,返回值也可以命名。命名后,最后返回只需写return即可,也可以根据命名的返回值return。
直接调用return不带结果,那么则返回 函数返回值定义的顺序进行结果返回。
package mainimport "fmt"func main() { a, b := getresult(5, 6) fmt.Println(a, b)}// 要求:给出长方形的两个变长,得出长方形的周长和面积// 可以在定义函数时,指定函数的返回值变量名func getresult(x, y int) (zhouchang, mianji int) { zhouchang = (x + y) * 2 mianji = x * y //函数定义处返回值命名了,return时要么和命名的变量名一样,要么可以直接不写 //return zhouchang, mianji return}
return的结果值命名和定义函数返回值的命名无关.
5. 可变参数函数
当一个函数的参数类型确定,参数的个数不确定,可以使用可变参数
可变参数函数是一种可以接受可变数量的参数的函数,通过使用三个省略号…来声明可变参数,可以使得函数接受任意数量的相同类型的参数。
可变参数函数在调用时,传递给函数的参数会被当作一个切片传递给函数。在函数内部,可以使用切片来访问和操作这些参数。
类似于python中的普通收集参数
语法格式
func functionName(参数名 ... 参数类型) returnType { // 函数体 return returnValue // 可选 }
这里面参数名表示的参数是一个切片,可以循环取出里面的值
如果函数有其他指定的参数,可变参数必须放在函数的最后一个参数位置。比如下面的可变参数nums,放在函数的最后一个参数位置
package mainimport "fmt"func main() { fmt.Println(getSum(10, 20, 30))}// 可变参数: 一个函数的参数类型确定,参数的个数不确定,可以使用可变参数// 可变参数如果有多个参数必须放在最后一个参数// 求和 , 参数是可变的,intfunc getSum(nums ...int) int { sum := 0 fmt.Println("可变参数的长度为:", len(nums)) //循环通过下标取出nums中的值 for i := 0; i < len(nums); i++ { fmt.Println("可变参数下标", i, ":", nums[i]) // 取出来 //sum = sum + nums[i] sum += nums[i] } return sum}// 接收多个参数 nums 可变参数// 使用下标来接收,下标是从0开始的// nums : 100,200,300,400,500// nums[0] = 100// nums[1] = 200// nums[2] = 300// 了解传递了多少个数字 len()函数,获取可变参数的长度
6. 函数的参数传递
Go语言默认使用按值传递,这意味着传递给函数的参数是原始数据的副本。对副本的任何修改都不会影响原始数据。但是,如果传递的是指针,则可以通过指针修改原始数据。
调用函数时,可以通过两种方式来传递参数:一种是值传递,另一种是引用传递。
值传递是指在调用函数时,将实际参数复制一份传递到函数中。这样,在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递是指在调用函数时,将实际参数的地址传递到函数中。这样,在函数中对参数所进行的修改,将影响到实际参数。
默认情况下,Go语言使用的是值传递,即在调用过程中不会影响到实际参数。
1、值传递
示例:按值传递
package mainimport "fmt"func increment(x int) { x++ // 只修改了副本}func main() { y := 5 increment(y) fmt.Println(y) // 输出: 5,因为y的值没有被修改}
2、引用传递
示例:按引用传递(通过指针)
引用传递,在定义函数时和参数操作时,都要在参数类型或参数名的前面加*
package mainimport "fmt"func increment(x *int) { *x++ // 修改了原始数据}func main() { y := 5 increment(&y) fmt.Println(y) // 输出: 6,因为y的值被修改了}
7. 函数中作用域
函数作用域
局部变量
1、函数内部定义的变量,只能在函数内部调用
全部变量(全局变量)
1、函数外部定义的变量,默认我们定义在上面,方便文件统一查看和管理全局变量
定义一个只在 if中生效的变量 if 临时变量(a,b := 1,2);条件判断{}
小作用域可以用到大作用域中的变量,反之则不行。
对于很多一次性的变量,都可以这么写
package mainimport "fmt"// 函数作用域// 局部变量// 1、函数内部定义的变量,只能在函数内部调用// 全部变量(全局变量)// 1、函数外部定义的变量,默认我们定义在上面,方便文件统一查看和管理全局变量var num int = 1func main() { temp := 100 // 定义一个只在 if 中生效的变量 if 临时变量(a,b := 1,2);条件判断{} // 小作用域可以用到大作用域中的变量,反之则不行。 // 对于很多一次性的变量,都可以这么写 // 生产中我们尽量优先使用局部变量 if a := 1; a <= 10 { fmt.Println(temp) fmt.Println(num) fmt.Println(a) // 就近原则 if a := 2; a <= 10 { fmt.Println(a) } } fmt.Println(num)}func f1() { fmt.Println(num)}func f2() {}
8. 递归函数
在Go语言中,可以使用递归函数,也就是一个函数在自身内部调用自身。
递归函数通常用于解决需要重复执行相同操作的问题,比如:计算阶乘、斐波那契数列等。
需要注意的是,递归函数必须有一个终止条件。否则,会无限递归下去,导致栈溢出甚至程序崩溃。
package mainimport "fmt"/*定义:一个函数自己调用自己,就叫做递归函数注意:递归函数需要有一个出口,逐渐向出口靠近,没有出口就会形成死循环。*/func main() { // overflows 栈溢出 sum := getSum2(10) fmt.Println(sum)}func getSum2(n int) int { //fmt.Println(n) //递归出口 if n == 1 { return 1 } //将自己返回,自己调用自己 return getSum2(n-1) + n}// 假设 getSum(5)// 求和 sum 1 + 2 + 3 + 4 + 5// getSum(5)☟=15// getSum(4)☟=10 + 5// getSum(3)☟=6 + 4// getSum(2)☟=3 + 3// // getSum(1)=1 + 2
如果计算的数太大,会造成内存溢出
fatal error: stack overflow
递归步骤分析
递归计算斐波那契数
利用递归计算斐波那契数列第n个值是多少
package mainimport "fmt"func main() { fmt.Println(feibo(5))}// 使用递归实现斐波那契数列,计算出第n个值是多少// 斐波那契数列 1 1 2 3 5 8 13 .....func feibo(n int) int { if n == 1 || n == 2 { return 1 } //第n个数是第n-1个数与第n-2个数的和 return feibo(n-1) + feibo(n-2)}