Golang 函数声明及调用 Link to heading

函数声明 Link to heading

Golang 中函数的声明由四个部分组成需要用到func关键字,方法名,形参,返回值等下面来看一个几个完整的函数声明。同时在 Go 中,所有函数都必须直接声明在包级代码块中。 或者说,任何一个函数都不能被声明在另一个函数体内。 虽然匿名函数但匿名函数定义不属于函数声明。

// 函数返回匿名结果值
func addNumber(a int, b int) int {

    return a + b
}

// 函数返回具名结果值,返回值需使用小括号包裹
func addNumber(a int , b int) (c int) {
  c = a + b

  // 下面的return 等于 return
  return
}

// 多个返回结果值
func addOne(a, b, c int) (int, int, int) {
    return a + 1, b + 1, c + 1
}

// 指针类型参数, 无返回值
func addTwo(a *int) {
    t := *a
    *a = t + 2
}

Golang 的函数参数和返回值如果为具名,则可以看作是一个标准的的、省略了var关键字的变量声明表达式。

需要注意的是 Golang 中函数形参是没有默认值的,并且 Golang 官方表示将来也没有计划支持该特性。

函数调用 Link to heading

一个声明的函数可以通过它的名称和一个实参列表来调用之。 一个实参列表必须用小括号括起来。 实参列表中的每一个单值实参对应着(或称被传递给了)一个形参。

注意:函数传参也属于赋值操作。在传参中,各个实参被赋值给各个对应形参。

一个实参值的类型不必一定要和其对应的形参声明的类型一样。 但如果一个实参值的类型和其对应的形参声明的类型不一致,则此实参必须能够隐式转换到其对应的形参的类型。

如果一个函数带有返回值,则它的一个调用被视为一个表达式。如果此函数返回多个结果,则它的每个调用被视为一个多值表达式。 一个多值表达式可以被同时赋值给多个目标值(数量必须匹配,各个输出结果被赋值给相对应的目标值)。

下面代码完整展示了如何调用函数:

// go_func.go
package main

import "fmt"

func addNumber(a int, b int) int {
	fmt.Println("---Function addNumber()----")
	return a + b
}

func addNumber2(a int, b int) (c int) {
	fmt.Println("---Function addNumber2()----")
	c = a + b
	return
}

func addOne(a, b, c int) (int, int, int) {
	fmt.Println("---Function addOne()----")
	return a + 1, b + 1, c + 1
}

func addTwo(a *int) {
	fmt.Println("---Function addTwo()----")
	t := *a
	*a = t + 2
}

func main() {
	a := 1
	b := 2
	c := 3
	d := 4

	x := addNumber(a, b)
	fmt.Println(x)

	y := addNumber2(a, b)
	fmt.Println(y)

	z, v, n := addOne(a, b, c)
	fmt.Println(z, v, n)

	addTwo(&d)
	fmt.Println("Current d:", d)
}
$ go run go_func.go
---Function addNumber()----
3
---Function addNumber2()----
3
---Function addOne()----
2 3 4
---Function addTwo()----
Current d: 6

匿名函数 Link to heading

Golang 支持匿名函数,既未指定函数名的函数。匿名函数不能独立存在在包中, 匿名函数可以在函数内部调用,也可以做参数传递。这样的形式类似于 Ruby 中的block,下面我们实现几个匿名函数的例子:

// go_func02.go
package main

import "fmt"

// 匿名函数作为参数,实现回调函数
func sumNumbers(numbers []int, callback func(int)) {
	i := 0
	for _, n := range numbers {
		i += n
	}

	callback(i)
}

func main() {
	// 小括号代表匿名函数立即执行
	func() {
		fmt.Println("我是一个无需参数无返回值的匿名函数")
	}()

	// 可以将匿名函数赋值给函数变量
	doubleNumber := func(n int) int {
		fmt.Println("doubleNumber function")
		return n * 2
	}

	n := doubleNumber(2)
	fmt.Println(n)

	sumNumbers([]int{1, 2, 3, 4, 5}, func(i int) {
		if i > 5 {
			fmt.Println("总和大于五")
		} else if i == 5 {
			fmt.Println("总和等于五")
		} else {
			fmt.Println("总和小于五")
		}
	})
}
$ go run go_func02.go

我是一个无需参数无返回值的匿名函数
doubleNumber function
4
总和大于五
```s