函数定义
GO语言中的函数定义如下:
func functionName([parameter list]) [returnTypes]{
//body
}
- functionName:代表函数名。
- parameter list:代表参数列表,函数的参数是可选的,可以包含参数也可以不包含参数。
- returnTypes:返回值类型,返回值是可选的,可以有返回值,也可以没有返回值。
- body:用于写函数的具体逻辑
传递
GO语言中存在值与引用,所以在使用函数时也需要明白两者的传递方式。
- 值传递是指在函数调用过程中将实参拷贝一份到函数中,这样在函数中如果对参数进行修改,将不会影响到实参。
- 引用传递是指在函数调用过程中将实参的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实参。
变长参数
GO语言中的函数可以放置数组、切片等变长类型作为输入入参。但是需要注意的是,变长参数需要放置函数参数的最后一个。
func main() {
slice := []int{7, 9, 3, 5, 1}
x := min(slice...)
fmt.Printf("The minimum is: %d", x)
}
func min(s ...int) int {
if len(s) == 0 {
return 0
}
min := s[0]
for _, v := range s {
if v < min {
min = v
}
}
return min
}
多返回值
与python一样,GO中也可以在函数中返回多个值。通过返回结果与一个错误值,这样可以使函数的调用者很方便的知道函数是否执行成功,这样的模式也被称为command,ok模式。进行多返回值需要使用()进行标记。
func div(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("The divisor cannot be zero.")
}
return a / b, nil
}
func main() {
result, err := div(1, 2)
if err != nil {
fmt.Printf("error: %v", err)
return
}
fmt.Println("result: ", result)
}
或者
func main() {
if result, err := div(1, 2); err != nil {
fmt.Printf("error: %v", err)
return
} else {
fmt.Println("result: ", result)
}
}
命名返回值
除了上面支持的多返回值,在go语言中还可以给返回值命名,当需要返回的时候,我们只需要一条简单的不带参数的return语句。
func div(a, b float64) (result float64, err error) {
if b == 0 {
return 0, errors.New("被除数不能等于0")
}
result = a / b
return
}
可以发现,函数名后面有两个括号,后面一个就代表返回值的名称了。
匿名函数
和其他程序语言一样,GO语言中也有匿名函数。
func main() {
f := func() string {
return "hello world"
}
fmt.Println(f())
}
闭包
闭包可以解释为一个函数与这个函数外部变量的一个封装。粗略的可以理解为一个类,类里面有变量和方法,其中闭包所包含的外部变量对应着类中的静态变量。 为什么这么理解,首先让我们来看一个例子。
func add() func(int) int {
n := 10
str := "string"
return func(x int) int {
n = n + x
str += strconv.Itoa(x)
fmt.Print(str, " ")
return n
}
}
func main() {
f := add()
fmt.Println(f(1))
fmt.Println(f(2))
fmt.Println(f(3))
f = add()
fmt.Println(f(1))
fmt.Println(f(2))
fmt.Println(f(3))
}