Listening to the Words

go学习之基本函数

介绍

每一个程序都包含很多的函数:函数是基本的代码块

Go 里面有三种类型的函数:

  1. 普通的带有名字的函数
  2. 匿名函数或者 lambda 函数
  3. 方法

除了 main ()、init () 函数外,其它所有类型的函数都可以有参数与返回值。函数参数、返回值以及它们的类型被统称为函数签名。

作为提醒,提前介绍一个语法:

这样是不正确的 Go 代码:

func g()
{
}

它必须是这样的:

func g() {
}

实例:

package main

func main() {
    println("In main before calling greeting")
    greeting()
    println("In main after calling greeting")
}

func greeting() {
    println("In greeting: Hi!!!!!")
}

函数定义

Go语言中定义函数使用func关键字,具体格式如下:

func 函数名(参数)(返回值){
    函数体
}

注意:

  • 函数名:由字母、数字、下划线组成。但函数名的第一个字母不能是数字。在同一个包内,函数名也称不能重名(包的概念详见后文)。
  • 参数:参数由参数变量和参数变量的类型组成,多个参数之间使用,分隔。
  • 返回值:返回值由返回值变量和其变量类型组成,也可以只写返回值的类型,多个返回值必须用()包裹,并用,分隔。
  • 函数体:实现指定功能的代码块

我们先来定义一个求两个数之和的函数:

func intSum(x int, y int) int {
    return x + y
}

还可以定义一个void函数:

func sayGoodeBye() {
    fmt.Println("byebye Gakki")
}

函数调用

func main() {
    sayGoodBye()
    ret := intSum(10, 20)
    fmt.Println(ret)
}

参数

go中不支持隐式参数,每个参数都必须入参,如果相同可以省略类型

//
func intSum(x, y int) int {
    return x + y
}

上面的代码中,intSum函数有两个参数,这两个参数的类型均为int,因此可以省略x的类型,因为y后面有类型说明,x参数也是该类型

可变参数

相似于PHP,go中也有可变参数类型,使用方式相同

可变参数是指函数的参数数量不固定。Go语言中的可变参数通过在参数名后加…来标识。

注意:可变参数通常要作为函数的最后一个参数。

举个例子:

func intSum2(x ...int) int {
    fmt.Println(x) //x是一个切片
    sum := 0
    for _, v := range x {
        sum = sum + v
    }
    return sum
}

调用上面的函数:

ret1 := intSum2()
ret2 := intSum2(10)
ret3 := intSum2(10, 20)
ret4 := intSum2(10, 20, 30)
fmt.Println(ret1, ret2, ret3, ret4) //0 10 30 60

本质上可变参数是通过切片来实现的

返回值

Go语言中通过return关键字向外输出返回值。

多返回值

Go语言中函数支持多返回值,函数如果有多个返回值时必须用()将所有返回值包裹起来。

举个例子:

func calc(x, y int) (int, int) {
    sum := x + y
    sub := x - y
    return sum, sub
}

返回值命名

函数定义时可以给返回值命名,并在函数体中直接使用这些变量,最后通过return关键字返回。

例如:

func calc(x, y int) (sum, sub int) {
    sum = x + y
    sub = x - y
    return
}

当我们的一个函数返回值类型为slice时,nil可以看做是一个有效的slice,没必要显示返回一个长度为0的切片

func someFunc(x string) []int {
    if x == "" {
        return nil // 没必要返回[]int{}
    }
    ...
}

变量作用域

全局变量和局部变量

package main

import "fmt"

//定义全局变量num
var num int64 = 10

func testGlobalVar() {
    fmt.Printf("num=%d\n", num) //函数中可以访问全局变量num
}
func main() {
    testGlobalVar() //num=10
}

类似于javascript,在函数体外通过var声明的是全局变量,在函数体声明的变量作用域仅在函数内

函数类型与变量

定义函数类型

我们可以使用type关键字来定义一个函数类型,具体格式如下:

type calculation func(int, int) int

上面语句定义了一个calculation类型,它是一种函数类型,这种函数接收两个int类型的参数并且返回一个int类型的返回值。

上面语句定义了一个calculation类型,它是一种函数类型,这种函数接收两个int类型的参数并且返回一个int类型的返回值。

func add(x, y int) int {
    return x + y
}

func sub(x, y int) int {
    return x - y
}

add和sub都能赋值给calculation类型的变量。

函数类型变量

我们可以声明函数类型的变量并且为该变量赋值:

func main() {
    var c calculation               // 声明一个calculation类型的变量c
    c = add                         // 把add赋值给c
    fmt.Printf("type of c:%T\n", c) // type of c:main.calculation
    fmt.Println(c(1, 2))            // 像调用add一样调用c

    f := add                        // 将函数add赋值给变量f1
    fmt.Printf("type of f:%T\n", f) // type of f:func(int, int) int
    fmt.Println(f(10, 20))          // 像调用add一样调用f
}
点赞