学Golang的第四天!

今天学习了defer跟slice切片(数组)

首先defer简单来说就是一个关键字,用于延迟执行一个函数调用,它会在当前函数体结束前触发,并且是先进后出的,因为是堆栈

package main

import "fmt"

func main() {
    defer fmt.Println("main执行结束了1")
    defer fmt.Println("main执行结束了2")

    fmt.Println("main正在执行")
}

例如上面的代码执行结果就是:
执行结果
会看到,main执行结束了1是最后才触发的;再举个例子:

package main

import "fmt"

func test1() int {
    fmt.Println("test1执行")
    return 0
}

func test2() int {
    fmt.Println("test2执行")
    return 0
}

func test3() int {
    defer test1()
    return test2()
}

func main() {
    test3()
}

上面的执行结果就是:先执行了return返回的test2,然后再执行了defer test1(),因为执行到rerun时,函数结束,然后触发了defer

然后说到数组

声明数组的方式有两种:

package main

import "fmt"

func main() {
    // 第一种,固定长度的数组
    var arr1 = [6]int{1, 2, 3, 4, 5, 6}
    // 第二种,根据初始值自动推断长度
    var arr2 = []int{1, 2, 3}

    for i := 0; i < len(arr1); i++ {
        fmt.Println(arr1[i])
    }

    fmt.Println("=============")

    // 类似于php的foreach
    for _, value := range arr2 {
        fmt.Println(value)
    }
}

然后说一下这两者定义的区别,例如函数调用里:

package main

import "fmt"

func test1(arr1 [6]int) {
    for i := 0; i < len(arr1); i++ {
        fmt.Println(arr1[i])
    }

    arr1[0] = 666
}

func test2(arr2 []int) {
    for i := 0; i < len(arr2); i++ {
        fmt.Println(arr2[i])
    }
    arr2[0] = 666
}

func main() {
    // 第一种,固定长度的数组
    var arr1 = [6]int{1, 2, 3, 4, 5, 6}
    // 第二种,根据初始值自动推断长度
    var arr2 = []int{1, 2, 3}

    test1(arr1)                      // 发现输出之后,0号元素还是1,说明传递的是值拷贝
    fmt.Println("arr1[0]:", arr1[0]) // 1

    fmt.Println("=============")

    test2(arr2)                      // 发现输出之后,0号元素变成了666,说明传递的是地址拷贝
    fmt.Println("arr2[0]:", arr2[0]) // 666
}

数组执行结果

无标签
打赏
评论区
头像