• go慢速入门——函数


    函数

    go中的函数非常重要,因为go没有类那套东西,因此函数go中最重要的单元。go中函数声明形式如下所示:

    func 函数名(参数列表)(返回值列表){
        函数体
    }
    
    • 1
    • 2
    • 3

    go中使用关键字func定义函数,函数名必须是合法的标识符。在go中,一个函数可以有多个返回值。函数体必须用花括号包起来。例如:

    package main
    
    import "fmt"
    
    func main() { // 程序的main入口函数必须不带任何输入参数和返回结果。
    	fmt.Println(add(1, 2))
    	fmt.Println(mul(3, 4))
    }
    
    func add(a int, b int) int { //只有一个匿名返回值的时候,可以省略返回值列表外面的小括号;否则不能省略小括号。
    	var c = a + b
    	return c
    }
    
    func mul(a int, b int) (sum int) { // 一个具名返回值,需要使用小括号。
    	sum = a * b
    	return // 由于在返回值列表中声明了返回值,因此在return后面可以省略掉sum。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    函数参数和函数返回值是由标识符和类型组成的,不像变量定义的时候,需要关键字var。

    Go不支持输入参数默认值。每个返回结果的默认值是它的类型的零值。
    和普通的变量声明一样,如果若干连续的输入参数或者返回结果的类型相同,则在它们的声明中可以共用一个类型。例如:

    func SquaresOfSumAndDiff(a, b int64) (s, d int64) {     // a,b,s,d都是int64类型。
    	return (a+b) * (a+b), (a-b) * (a-b)
    	// 上面这行等价于下面这行:
    	// s = (a+b) * (a+b); d = (a-b) * (a-b); return
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意,尽管在上面这个函数声明的返回结果都是具名的,函数体内的return关键字后仍然可以跟返回值。
    函数调用的时候,一个实参值的类型不必一定要和其对应的形参声明的类型一样。 但如果一个实参值的类型和其对应的形参声明的类型不一致,则此实参必须能够隐式转换到其对应的形参的类型。

    一个函数的声明可以出现在它的调用之前,也可以出现在它的调用之后。一个函数调用可以被延迟执行或者在另一个协程(goroutine,或称绿色线程)中执行。

    函数调用的退出阶段

    在Go中,当一个函数调用返回后(比如执行了一个return语句或者函数中的最后一条语句执行完毕), 此调用可能并未立即退出。一个函数调用从返回开始到最终退出的阶段称为此函数调用的退出阶段(exiting phase)。 函数调用的退出阶段的意义将在延迟函数中体现出来。
    这是go语言的特色。

    匿名函数

    现在绝大多数的编程语言都支持匿名函数。匿名函数就是没有名称的函数,例如:

    package main
    
    func main() {
    	// 这个匿名函数没有输入参数,但有两个返回结果。
    	x, y := func() (int, int) {
    		println("This function has no parameters.")
    		return 3, 4
    	}() // 一对小括号表示立即调用此函数。不需传递实参。
    
    	// 下面这些匿名函数没有返回结果。
    
    	func(a, b int) {
    		println("a*a + b*b =", a*a + b*b) // a*a + b*b = 25
    	}(x, y) // 立即调用并传递两个实参。
    
    	func(x int) {
    		// 形参x遮挡了外层声明的变量x。
    		println("x*x + y*y =", x*x + y*y) // x*x + y*y = 32
    	}(y) // 将实参y传递给形参x。
    
    	func() {
    		println("x*x + y*y =", x*x + y*y) // x*x + y*y = 25
    	}() // 不需传递实参。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    注意,在go中,不能再函数内定义函数,如果上面这些匿名函数不被直接调用,那么将会导致错误。上例中的最后一个匿名函数处于变量x和y的作用域内,所以在它的函数体内可以直接使用这两个变量。 这样的函数称为闭包(closure)。

    实际上一个匿名函数可以被赋值给某个函数类型的值,从而我们不必在定义完此匿名函数后立即调用它,而是可以在以后合适的时候再调用它。

  • 相关阅读:
    一年跳一行,南京校区小哥哥最终选择在软件测试扎根,入职就拿9k!
    arduino(esp8266)驱动74hc595进行流水灯异常一例
    Mybatis简介(二)
    思腾云计算
    kubectl应用
    Numpy:打开通往高效数值计算的大门
    Topic 19. 临床预测模型之输出每个患者列线图得分 (nomogramFormula)
    [机缘参悟-32]:鬼谷子-抵巇[xī]篇-面对危险与问题的五种态度
    我出手了!
    JVM虚拟机学习笔记之-5. 字节码执行引擎
  • 原文地址:https://blog.csdn.net/zy010101/article/details/126056099