一、以下代码的输出内容为

package main
import (
    "fmt"
)
func main() {
    defer_call()
}
func defer_call() {
    defer func() { fmt.Println("打印前") }()
    defer func() { fmt.Println("打印中") }()
    defer func() { fmt.Println("打印后") }()
    panic("触发异常")
}

答案

打印后
打印中
打印前
panic: 触发异常

解析

考查defer和panic组合的情况,在有panic时,会先执行defer然后再把恐慌传递出去。

更多相关内容可查看defer常见的坑以及官方文档描述

二、以下代码有什么问题

package main
import (
    "fmt"
)
type student struct {
    Name string
    Age  int
}
func pase_student() map[string]*student {
    m := make(map[string]*student)
    stus := []student{
        {Name: "zhou", Age: 24},
        {Name: "li", Age: 23},
        {Name: "wang", Age: 22},
    }
    for _, stu := range stus {
        m[stu.Name] = &stu
    }
    return m
}
func main() {
    students := pase_student()
    for k, v := range students {
        fmt.Printf("key=%s,value=%v \n", k, v)
    }
}

答案

key=zhou,value=&{wang 22} 
key=li,value=&{wang 22} 
key=wang,value=&{wang 22} 

解析

for循环使用stu遍历时,stu只是一个临时变量,遍历过程中指针地址不变,所以后面的赋值都是指向了同一个内存区域,导致最后所有的信息都一致。

其实这个现象不仅仅存在于go中,c/c++python中也存在,原理也都一样。

修改方案

for i, _ := range stus {
    stu:=stus[i]
    m[stu.Name] = &stu
}

三、下面的代码会输出什么,并说明原因

package main

import (
    "sync"
    "fmt"
)

func main() {
    wg := sync.WaitGroup{}
    wg.Add(21)
    for i := 0; i < 10; i++ {
        go func() {
            fmt.Println("i: ", i)
            wg.Done()
        }()
    }
    for j := 0; j < 10; j++ {
        go func(x int) {
            fmt.Println("j: ", x)
            wg.Done()
        }(j)
    }
    wg.Wait()
}

答案

j:  9
i:  10
j:  0
j:  1
j:  2
j:  3
j:  4
j:  5
j:  6
i:  10
i:  10
i:  10
i:  10
i:  10
j:  8
i:  10
i:  10
i:  10
j:  7
i:  10

解析

第一个循环中的打印是在函数中打印的,i是外部的变量,执行go func(){}后代码不会立即执行,一般当该代码片段被调度器执行的时候,for循环已经全部执行完毕,此时的i为10。所以i会打印10个10,而j则会无序打印1-10。

四、下面代码会输出什么

type People struct{}
func (p *People) ShowA() {
    fmt.Println("showA")
    p.ShowB()
}
func (p *People) ShowB() {
    fmt.Println("showB")
}
type Teacher struct {
    People
}
func (t *Teacher) ShowB() {
    fmt.Println("teacher showB")
}
func main() {
    t := Teacher{}
    t.ShowA()
}

答案

showA
showB

解析

go中没有继承,只有组合。Teacher中的People是一个匿名对象,通过它调用的函数都是自身的。

最后修改:2018 年 04 月 11 日
喜欢就给我点赞吧