Go的函数
函数的定义格式
- 用func表示这是Go函数的定义, 类似于python的def
- func后面紧跟着函数名
- 函数名之后小括号里面表示形参, 需要写出形参的名称和类型
注:
和变量的定义不一样, 函数定义时候的形参不需要加上var
- 在形参的定义之后写上返回值的类型
注:
和c++不一样, 和python一样 ,Go的返回值也可以是多个返回值
- 紧接着大括号里面写函数定义
- 见例子1:
package main
import "fmt"
func print(param, param2 int) {
fmt.Println(param, param2)
}
func main() {
print(10, 20)
}
- 见例子2:
package main
import "fmt"
func function(param int) (int, int) {
return param, 1
}
func main() {
fmt.Println(function(10))
}
- Go语言的返回值可以有返回值的名称, 让我们来看代码:
package main
import "fmt"
func function(param int) (res int) {
res = param
return
}
func main() {
fmt.Println(function(10))
}
注:
其实这种写法就是c++的函数调用内部发生情况的折射, c++的函数调用就是传递了一个变量去接收, 之后retun, 适用于有无返回值
形参
- 如果是相同类型的形参, 可以形参这么写:
func print(param, param2 int)
- 但是如果是不同类型的形参, 则这么写:
func print(param float32, param2 int)
函数的定义位置
- 先看代码:
package main
import "fmt"
func main() {
print()
}
func print() {
fmt.Println("hhhhhh")
}
注:
如果是c++等编译型语言, 先使用后定义会报错, 但是在Go, python之中可以这么写, 注意
Go不定参数
- c++之中的不定参数是…, 然后用va_list接收
- Go之中也有不定参数, 见下例
package main
import "fmt"
func print(args... string) {
for _, data := range args {
fmt.Println(data)
}
}
func main() {
print("aaa", "bbb")
}
注:
Go的不定参数必须放在形参的最后一个
…之前的不定参数名称可以自己随便取, 比方说换成tmp… int都可以
注意, args…是一体, 不要拆分
Go函数类型
- 其实这里说的就是类似于C++之中的函数指针, 可以通过它实现回调机制
package main
import "fmt"
func function(param int) (res int) {
res = param
return
}
func main() {
type functype func(int) int
var myfunc functype = function
fmt.Println(myfunc(10))
}
Go匿名函数
- 先来看代码:
package main
import "fmt"
func main() {
f := func(param int) {
fmt.Println(param)
}
f(10)
}
- 我们都知道c++之中函数定义的内部再定义函数是不行的, 但是后来c++拥有了lambda实现了这一点
- Go的匿名函数就是没有函数名称, 可以在函数定义内部进行匿名函数的定义, 可以类比lambda表达式理解
- Go匿名函数定义,调用一起写的写法;
package main
import "fmt"
func main() {
func(param int) {
fmt.Println(param)
}(10)
}
defer
- defer是延迟调用, 在函数结束前那时候才开始调用
- 如果有多个defer, 按照后进先出的顺序调用, 哪怕函数或者是某个延迟调用出现错误, 依旧会被执行
- 见代码
package main
import "fmt"
func main() {
defer fmt.Println("aaa")
defer fmt.Println("bbb")
defer fmt.Println("ccc")
}
ccc
bbb
aaa
main函数接收参数
- c++之中有argc, argv, envp
- Go之中借助于os包, 第一个参数始终都是exe那个文件, 注意
package main
import (
"fmt"
"os"
)
func main() {
args := os.Args
fmt.Println(len(args))
}