Go的函数

Posted by William Basics on Tuesday, April 27, 2021

Go的函数

Go函数的定义以 func 关键词开头。

匿名函数

Go支持匿名函数,常常用于函数式编程中。匿名函数又被称为 闭包(closure)

多个返回值的函数定义

func aFunction() (int, int, float64, string) { 
} 

代码示例

package main

import (
	"fmt"
	"os"
	"strconv"
)

func doubleSquare(x int) (int, int) {
	return x * 2, x * x
}

func main() {
	arguments := os.Args
	if len(arguments) < 2 {
		fmt.Println("arguments are required")
		return
	}

	x, err := strconv.Atoi(arguments[1])
	if err != nil {
		fmt.Println(err)
		return
	}

	square := func(s int) int {
		return s * s
	}

	fmt.Println("The square of", x, "is", square(x))

	fmt.Println(doubleSquare(x))
}

Go函数的返回值可命名

和C不同,Go函数的返回值是可命名的。并且,如果函数尾的return不带任何返回值的话,那么命名返回值将按照顺序 return给调用者。

package main 
 
import ( 
    "fmt" 
    "os" 
    "strconv" 
) 
 
func namedMinMax(x, y int) (min, max int) { 
    if x > y { 
        min = y 
        max = x 
    } else { 
        min = x 
        max = y 
    } 
    return 
} 

指针类型参数

package main 
 
import ( 
    "fmt" 
) 
 
func getPtr(v *float64) float64 { 
    return *v * *v 
} 

和C/C++一样,可以通过取值操作符 & 取得变量地址。

指针类型返回值

package main 
 
import ( 
    "fmt" 
) 
 
func returnPtr(x int) *int { 
    y := x * x 
    return &y 
} 

和C/C++不同,在Go中返回一个local变量得地址是完全OK的。分配给local变量的内存在函数返回时不会被回收。

返回函数的函数

package main 
 
import ( 
    "fmt" 
) 
 
func funReturnFun() func() int { 
    i := 0 
    return func() int { 
        i++ 
        return i * i 
    } 
} 

func main() { 
    i := funReturnFun() 
    j := funReturnFun() 
    
    fmt.Println("1:", i()) 
    fmt.Println("2:", i()) 
    fmt.Println("j1:", j()) 
    fmt.Println("j2:", j()) 
    fmt.Println("3:", i()) 
} 

函数作为参数

package main 
 
import "fmt" 
 
func function1(i int) int { 
    return i + i 
} 
 
func function2(i int) int { 
    return i * i 
} 

func funFun(f func(int) int, v int) int { 
    return f(v) 
} 

func main() { 
    fmt.Println("function1:", funFun(function1, 123)) 
    fmt.Println("function2:", funFun(function2, 123)) 
    fmt.Println("Inline:", funFun(func(i int) int {return i * i   *i}, 123)) 
} 

含有可变参数的函数

package main 
 
import ( 
    "fmt" 
    "os" 
) 
 
func varFunc(input ...string) { 
    fmt.Println(input) 
} 

func oneByOne(message string, s ...int) int { 
    fmt.Println(message) 
    sum := 0 
    for i, a := range s { 
        fmt.Println(i, a) 
        sum = sum + a 
    } 
    s[0] = -1000 
    return sum 
} 

func main() { 
    arguments := os.Args 
    varFunc(arguments...) 
    sum := oneByOne("Adding numbers...", 1, 2, 3, 4, 5, -1, 10) 
    fmt.Println("Sum:", sum) 
    s := []int{1, 2, 3} 
    sum = oneByOne("Adding numbers...", s...) 
    fmt.Println(s) 
} 

后面跟着类型的 ... 操作符被称为 打包操作符。slice后面跟着的 ... 被称为解包操作符。

(end.)