函数声明与调用
函数声明与调用
package main
import "fmt"
// sayHello 是一个无返回值函数
func sayHello(name string) {
fmt.Println("你好:", name)
}
// add 是一个有返回值函数
func add(a int, b int) int {
return a + b
}
// getUser 是一个多返回值函数
func getUser() (string, int) {
return "Tom", 20
}
func main() {
// 在 main 中调用无返回值函数
sayHello("Go")
// 在 main 中调用有返回值函数
result := add(10, 20)
fmt.Println("10 + 20 =", result)
// 在 main 中调用多返回值函数
name, age := getUser()
fmt.Println("姓名:", name)
fmt.Println("年龄:", age)
}几个特殊用法
// sum 是可变参数函数,可以接收多个 int 参数
func sum(nums ...int) int {
total := 0
for _, v := range nums {
total += v
}
return total
}
// calc 是命名返回值函数
func calc(a int, b int) (sum int, diff int) {
sum = a + b
diff = a - b
return
}匿名函数
package main
import "fmt"
// exec 接收一个函数参数并执行
func exec(fn func(int, int) int, a int, b int) {
fmt.Println("执行结果:", fn(a, b))
}
func main() {
// 1. 匿名函数:定义后立即调用
func() {
fmt.Println("这是第一个匿名函数")
}()
// 2. 匿名函数:带参数立即调用
func(name string) {
fmt.Println("你好:", name)
}("Go")
// 3. 匿名函数:赋值给变量后调用
add := func(a int, b int) int {
return a + b
}
fmt.Println("add =", add(10, 20))
// 4. 匿名函数:作为参数传递给其他函数
exec(func(a int, b int) int {
return a * b
}, 3, 4)
// 5. 匿名函数闭包:记住外部变量
count := 0
next := func() int {
count++
return count
}
fmt.Println("next =", next())
fmt.Println("next =", next())
fmt.Println("next =", next())
}闭包
package main
import "fmt"
func main() {
// 闭包:匿名函数 + 捕获外部作用域变量。
// 下面的 counter 闭包会记住 count 的值。
counter := createCounter()
fmt.Println("第一次调用 counter():", counter())
fmt.Println("第二次调用 counter():", counter())
fmt.Println("第三次调用 counter():", counter())
fmt.Println()
// 这个闭包会一直记住 sum,每次调用都会在上一次结果的基础上继续累加。
accumulator := createAccumulator()
fmt.Println("accumulator(10):", accumulator(10))
fmt.Println("accumulator(20):", accumulator(20))
fmt.Println("accumulator(30):", accumulator(30))
}
func createCounter() func() int {
count := 0
// 返回一个匿名函数。
// 虽然 createCounter 已经执行结束,
// 但这个匿名函数仍然可以访问并修改 count。
return func() int {
count++
return count
}
}
func createAccumulator() func(int) int {
sum := 0
// 这个匿名函数捕获了外部的 sum,
// 因此每次调用都会保留之前的计算结果。
return func(num int) int {
sum += num
return sum
}
}重要
**Go 的函数是一等公民,闭包就是函数一等公民最典型的体现。 **
闭包是指,一个函数,捕获了函数外部作用域的变量,函数可以读取、修改外部变量,变量生命周期脱离原函数,不会随原函数销毁。 此外,闭包也存在一些问题,尤其是需要并发或者循环处理时,存在比较严重的问题。比如:
for i := 0; i <3; i++ {
go func(){
fmt.Println(i) //全部打印3,捕获i的地址,不是当时值
}()
}
//正确写法
//修复:传参拷贝
for i :=0;i<3;i++{
go func(v int){
fmt.Println(v)
}(i)
}