go 语言学习笔记②
函数
格式
func 函数名(参数列表)(返回值类型) {
reuturn 多个返回值
}
无参 无返回值
package main
import "fmt"
func pa() {
fmt.Print("hello word")
}
func main() {
pa()
}
有参有返回值
package main
import "fmt"
func add(a int, b int) (c int) {
c = a + b
return
}
func main() {
fmt.Println(add(1, 2))
}
不定参数列表
列表中最后一个参数(通过切片实现)类py
package main
import "fmt"
func add(args ...int) (c int) {
for _, date := range args {
c += date
}
return
}
func main() {
fmt.Println(add(1, 2, 3, 4))
}
不定参数传递给另一个函数
全部传递
不定参数变量…
package main
import "fmt"
func add01(all ...int) (sum int) {
for _, date := range all {
sum += date
}
return sum
}
func add(args ...int) (c int) {
c = add01(args...)
return c
}
func main() {
fmt.Println(add(1, 2, 3, 4))
}
传递一部分
不定参数变量[开始 : 结束] …
package main
import "fmt"
func add01(all ...int) (sum int) {
for _, date := range all {
sum += date
}
return sum
}
func add(args ...int) (c int) {
c = add01(args[:2]...)
return c
}
func main() {
fmt.Println(add(1, 2, 3, 4))
}
返回值
给返回值起变量名 给方便在函数里面进行运算
同一类型的返回值可以只在最后一个后面写类型(不建议, 容易乱)
递归函数
自己调用自己
注意终止条件
package main
import "fmt"
func sum(a int) int {
if a == 1 {
return 1
}
return a + sum(a-1)
}
func main() {
fmt.Println(sum(10))
}
函数类型
函数也是一个数据类型,通过type给一个函数类型起名
type FuncType func(int , int) int
没有函数名字, 没有函数体
FuncType 他是一个函数类型
var nowUse FuncType
nowUse = add
nowUse = minn
可以指向参数列表和返回值相同的函数, 并使用该函数
类java多态
回调函数
回调函数:函数有一个参数列表是函数类型
多态:多种形态, 调用同一个接口, 不同的表现, 可以实现不同的表现
//先定义后调用
package main
import "fmt"
type FuncType func(int, int) int
func add(a int, b int) int {
return a + b
}
func re(a int, b int) int {
return a - b
}
func mul(a int, b int) int {
return a * b
}
func div(a int, b int) int {
return a / b
}
func solve(a int, b int, nowUse FuncType) int {
return nowUse(a, b)
}
func main() {
fmt.Println(solve(1, 2, add))
fmt.Println(solve(1, 2, re))
fmt.Println(solve(4, 2, mul))
fmt.Println(solve(4, 2, div))
}
匿名函数
没有函数名
package main
import "fmt"
func main() {
a := 10
str := "abc"
f1 := func() {
fmt.Println("第一个匿名函数")
fmt.Println(a)
fmt.Println(str)
}
f1() //调用第一个匿名函数
func() {
fmt.Println("第二个匿名函数")
fmt.Println(str)
fmt.Println(a)
}() //声明后之直接调用
f1() //调用第一个匿名函数
}
结果:
第一个匿名函数
10
abc
第二个匿名函数
abc
10
第一个匿名函数
10
abc
闭包
闭包:一个函数“捕获”了和他在同一作用域的其他常量和变量。这就意味着当闭包被调用的时候,不管程序什么地方调用,闭包能够使这些常量或变量。他不关心这些捕获的变量和常量是否已经超出了作用域,所以只要有闭包还在使用它 , 这些变量就还会存在
匿名函数实现
以引用的方式捕获外部变量(可以在闭包内改变外部的变量值)
package main
import "fmt"
func test() func() int {
var x int
return func() int {
x++
return x * x
}
}
func main() {
f := test()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
}
结果
1
4
9
16
defer
用于延迟一个函数或方法的执行, defer语句只能出现在函数或方法的内部
package main
import "fmt"
func main() {
defer fmt.Println("1")
fmt.Println("2")
}
结果
2
1
多个defer 先执行 后面的 先进后出
局部变量
定义在函数体内的变量 只能在函数里使用 离开作用域会释放空间
全局变量
定义在函数体外的变量, 在每一个函数都能使用
同名的局部变量和全局变量使用局部变量(就近原则)