Go语言学习笔记(四)Go语言函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kang___xi/article/details/86530488

        Go语言的函数声明以func标识,后面紧接着函数名、参数列表、返回参数列表以及函数体。

1.普通函数的声明形式

func 函数名(参数列表) (返回参数列表){
    //函数体
}

注意:
在同一个包内,函数名不能相同
参数列表中如果多个参数类型相同,则可放在一起声明。如func test(a, b int) {}同时声明a, b为int类型
函数可以同时返回多个值

2.同一类型返回值

func typedTwoValues() (int, int) {
    return 1, 2
}

a, b = typedTwoValues()
fmt.Println(a, b)

3.带有变量名的返回值

func namedRetVallues() (a, b int) {
    a = 1
    b = 2
    return
}

当函数使用命名返回值时,可以在return中不填写返回值列表,如果填写也是可行的。

4.参数传递

        Go语言中传入和返回参数在调用和返回时都使用值传递,这里要注意的是指针、切片和map等引用型对象指向的内容在参数传递中不会发生复制,而是将指针进行复制,类似于创建一次引用。

5.函数变量

        在Go语言中,函数也是一种类型,可以和其他类型一样被保存在变量中。

func fire() {
    fmt.Println("call fire")
}

func foo1(a int) int{

}

var f1 func()   //定义函数变量f,无参无返回值
f1 = fire

var f2 func(int) int = foo1

6.匿名函数

        Go语言支持匿名函数,即在需要使用函数时,再定义函数,匿名函数没有函数名,只有函数体,函数可以被作为一种类型赋值给函数类型的变量,匿名函数也往往以变量方式被传递。

        匿名函数经常被用于实现回调函数、闭包等。

(1)匿名函数定义格式

func(函数列表) (返回参数列表) {
    //函数体
}

(2)定义时调用匿名函数

func(data int) {
    fmt.Println("hello", data)
}(100)

(3)将匿名函数赋值给变量

f := func(data int) {
    fmt.Println(data)
}

f(100)     //调用匿名函数


(4)匿名函数作为回调函数

func visit(list []int, f func(int)){
    //to do
    for _, v := range list {
        f(v)
    }
}

visit([]int{1, 2, 3}, func(data int) {
    fmt.Println(data)
})

(5)匿名函数实现操作封装

 var skill = map[string]func() {
    "fire":func() {
        fmt.Println("chicken fire")
    },
    "run":func() {
        fmt.Println("soldier run")
    },
}

7.变参函数

        所谓可变参数,是值参数数量不固定的函数形式。Go语言支持可变参数特性,函数声明和调用时没有固定数量的参数。

(1)变参函数定义格式

func 函数名(固定参数列表, v ... T) (返回参数列表) {
    //todo
}

可变参数一般被放置函数列表的末尾,前面是固定参数列表
v为可变参数变量,类型为[]T
T为可变参数的类型,如果T为interface{},传入的可以是任意类型

(2)所有参数都是可变参数

以fmt.Println()为例:
func Println(a ...interface{}) (n int, err error) {
    return Fprintln(os.Stdout, a...)
}

(3)部分参数是可变参数

以fmt.Printf()函数为例:

func Printf(format string, a ...interface{}) (n int, err error) {
    return Fprintf(os.Stdout, format, a...)
}

(4)在多个可变参数函数中传递参数

func rawPrint(rawList ...interface{}) {
    //todo
}

func Print(slist ...interface{}) {
    rawPrint(slist...)    //这种用法在切片的append()中也见过
}

func main() {
    Print("hello", 123)
}

8.defer(延迟执行语句)

       Go语言的defer语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处理的语句按defer的逆序进行执行。也就是说,先被defer的语句最后被执行,最后被defer的语句,最先被执行。

func main() {
    
    defer fmt.Println("defer begin")

    defer fmt.Println(1)

    defer fmt.Println(2)

    defer fmt.Println(3)

    defer fmt.Pritnln("defer end")
}

输出结果:
defer begin
defer end
3
2
1

通过defer声明调用的函数的调用顺序和C++析构的调用函数类似,都是一个栈的调用顺序、

猜你喜欢

转载自blog.csdn.net/kang___xi/article/details/86530488