摄影网站免费源码,0000网站建设,长沙网站设计认准智优营家,建设个人博客网站制作1. 引言
函数是编程中不可或缺的组成部分#xff0c;无论是在Go语言还是其他编程语言中#xff0c;函数都扮演着重要的角色。函数能够将一系列的操作封装在一起#xff0c;使得代码更加模块化、可重用和易于维护。
在本文中#xff0c;我们将详细介绍Go语言中函数的概念和…1. 引言
函数是编程中不可或缺的组成部分无论是在Go语言还是其他编程语言中函数都扮演着重要的角色。函数能够将一系列的操作封装在一起使得代码更加模块化、可重用和易于维护。
在本文中我们将详细介绍Go语言中函数的概念和使用方法包括函数的定义、参数和返回值、调用方式、可变参数、函数作为参数和返回值等方面的内容。
2. 函数的基本定义
在Go语言中定义函数需要按照以下语法
func functionName(parameter1 type1, parameter2 type2) returnType {// 函数体// 可以包含一系列的语句和操作return value // 返回值如果有
}其中各个部分的含义如下 func: 关键字用于定义函数。functionName: 函数名用于唯一标识该函数。parameter1, parameter2: 参数列表函数可以接收零个或多个参数。每个参数由参数名和参数类型组成多个参数之间使用逗号分隔。type1, type2: 参数的类型指定参数的数据类型。returnType: 返回类型指定函数的返回值的数据类型。如果函数没有返回值则返回类型为空。return value: 可选项用于返回函数的结果。如果函数定义了返回类型则需要使用return语句将结果返回给调用者。 下面是一个示例函数的定义
func add(a int, b int) int {sum : a breturn sum
}上述示例中函数名为add接收两个参数a和b类型为int并且返回类型也为int。函数体内部计算参数的和并将结果使用return语句返回。
3.1 值传递
传递是指在调用函数时将实际参数复制一份传递到函数中这样在函数中如果对参数进行修改将不会影响到实际参数。
默认情况下Go 语言使用的是值传递即在调用过程中不会影响到实际参数。
以下定义了 swap() 函数
package mainimport fmtfunc main() {/* 定义局部变量 */var a int 100var b int 200fmt.Printf(交换前 a 的值为 : %d\n, a)fmt.Printf(交换前 b 的值为 : %d\n, b)/* 通过调用函数来交换值 */swap(a, b)fmt.Printf(交换后 a 的值 : %d\n, a)fmt.Printf(交换后 b 的值 : %d\n, b)
}/* 定义相互交换值的函数 */
func swap(x, y int) int {var temp inttemp x /* 保存 x 的值 */x y /* 将 y 值赋给 x */y temp /* 将 temp 值赋给 y*/return temp
}运行结果
交换前 a 的值为 : 100
交换前 b 的值为 : 200
交换后 a 的值 : 100
交换后 b 的值 : 200
可见交换前后ab的值没变。 所以值传递不会改变所传入实参的值。只是复制一份值用于函数体执行而已。
3.2 引用参数
引用参数是通过将参数的地址传递给函数来进行传递的。这样函数就可以通过指针来间接地修改原始数据。因为传递指针只需要占用较小的内存所以其通常适用于需要修改原始数据或者数据量较大的场景。下面通过一个切片的例子来进行说明切片内部保存了数组的指针可以认为是传递了数组引用:
func appendValue(slice []int, value int) {slice append(slice, value)fmt.Println(Inside appendValue function:, slice)
}func main() {numbers : []int{1, 2, 3}appendValue(numbers, 4)fmt.Println(After function call:, numbers)
}输出结果为
Inside appendValue function: [1 2 3 4]
After function call: [1 2 3 4]在上述示例中appendValue函数接收一个切片作为引用参数slice并在函数内部使用append函数向切片中追加一个值。这个修改会影响到原始的numbers切片。
所以如果函数内想要修改参数值此时可以通过传递引用参数来达到这个目的。
2引用传递
引用传递是指在调用函数时将实际参数的地址传递到函数中那么在函数中对参数所进行的修改将影响到实际参数。
引用传递将指针参数传递到函数内以下是交换函数 swap() 使用了引用传递
package mainimport fmtfunc main() {var a int 100var b int 200fmt.Printf(交换前a的值为%d\n, a)fmt.Printf(交换前b的值为%d\n, b)/* 调用 swap() 函数* a 指向 a 指针a 变量的地址* b 指向 b 指针b 变量的地址*/swap(a, b)fmt.Printf(交换后a 的值 : %d\n, a)fmt.Printf(交换后b 的值 : %d\n, b)
}func swap(x, y *int) int {var temp inttemp *x /* 保存 x 的值 */*x *y /* 将 y 值赋给 x */*y temp /* 将 temp 值赋给 y*/return temp
}输出结果
交换前a 的值 : 100
交换前b 的值 : 200
交换后a 的值 : 200
交换后b 的值 : 100 注意 无论是值传递还是引用传递传递给函数的都是变量的副本不过值传递是值的拷贝。引用传递是地址的拷贝一般来说地址拷贝更为高效。而值拷贝取决于拷贝的对象大小对象越大则性能越低。map、slice、chan、指针、interface默认以引用的方式传递。 3.3 可变参数
Go语言支持可变参数函数即函数可以接受可变数量的参数。在Go语言中可变参数函数使用 ... 操作符来表示。该操作符放置在参数类型前面用于指示该参数可以接受多个值。具体语法如下
func myfunc(args ...int) { //0个或多个参数
}func add(a int, args…int) int { //1个或多个参数
}func add(a int, b int, args…int) int { //2个或多个参数
}其中param 是可变参数的名称Type 是可变参数的类型。在函数体内我们可以像处理切片一样处理可变参数使用循环或索引来遍历和访问参数的值。下面是一个使用可变参数函数的示例
func sum(numbers ...int) int {total : 0for _, num : range numbers {total num}return total
}func main() {result : sum(1, 2, 3, 4, 5)fmt.Println(Sum:, result)
}在上述示例中sum 函数使用可变参数 numbers 来接收多个整数值。在函数体内我们使用循环遍历 numbers 切片并累加每个整数值到 total 变量中。最后函数返回累加的总和。 实例 2使用切片赋值
在参数赋值时可以不用一个一个的赋值可以直接传递一个数组或者切片特别注意的是在参数后加上“…”即可。
使用 slice 对象做变参时必须展开。slice…
import (fmt
)func test(s string, n ...int) string {var x intfor _, i : range n {x i}return fmt.Sprintf(s, x)
}func main() {s :[] int{1,2,3}res :test(sum: %d,s...)println(res)
}4、函数返回值 返回值的忽略_标识符用来忽略函数的某个返回值。 Golang返回值不能用容器对象接收多返回值。只能用多个变量或 “_” 忽略。 多返回值可直接作为其他函数调用实参。
package mainfunc test() (int, int) {return 1, 2
}
func add(x, y int) int {return x y
}
func sum(n ...int) int {var x intfor _, i : range n {x i}return x
}func main() {println(add(test()))println(sum(test()))
}运行结果
3
33.命名返回值
Go 函数的返回值可以被命名就像在函数体开头声明变量。 返回值的名称应当具有一定的意义可以作为文档使用。 命名返回参数可看做与形参类似的局部变量最后由 return 隐式返回。
package mainfunc add(x, y int) (z int) {{ // 不能在一个级别引发 z redeclared in this block 错误。z x y// return // Error: z is shadowed during returnreturn // 必须显式返回。}
}
func main() {println(add(1, 2))
}注意命名返回参数可被同名局部变量遮蔽此时需要显式返回。
package mainfunc add(x, y int) (z int) {{ // 不能在一个级别引发 z redeclared in this block 错误。z x y// return // Error: z is shadowed during returnreturn z // 必须显式返回。}
}
func main() {println(add(1, 2))
}4.没有参数的 return 语句返回各个返回变量的当前值。这种用法被称作“裸”返回。 直接返回语句仅应当用在像下面这样的短函数中。在长的函数中它们会影响代码的可读性。
package mainimport fmtfunc add(a, b int) (c int) {c a breturn
}func calc(a, b int) (sum int, avg int) {sum a bavg (a b) / 2return
}
func main() {var a, b int 1, 2c : add(a, b)sum, avg : calc(a, b)fmt.Println(c, sum, avg)
}运行结果
3 3 1
在 Go 语言中函数是一等公民这意味着函数可以作为参数传递给其他函数也可以作为返回值返回。以下是一些函数作为实参的例子
实例1传递函数作为参数
package mainimport fmt// 定义一个函数它来接受一个函数作为参数
func applyFunction(x int, y func(int) int) int {return y(x)
}// 定义一个简单的函数用于增加
func addFive(x int) int {return x 5
}
func main() {result : applyFunction((10), addFive)fmt.Println(result)//输出15
}实例2使用匿名函数
在 Go 语言中匿名函数也称为立即执行函数或 lambda 表达式是一种没有名称的函数通常用于需要函数作为参数的场合。匿名函数可以在定义它们的代码块内立即使用也可以作为参数传递给其他函数。
package mainimport fmt
//applyFunction接受一个函数作为参数并使用这个函数处理输入值
func applyFunction(x int, f func(int) int) int {return f(x)
}
func main() {//定义并传递一个匿名函数result : applyFunction(10, func(x int) int {return x * 2})fmt.Println(result)//输出20
}