Golang经典笔试题及答案(上篇)

1. 写出下面代码输出内容

 
 
package main

import "fmt"

func main()  {
   defer_call()
}

func defer_call()  {
   defer func() {
      fmt.Println("打印前")
   }()
   defer func() {
      fmt.Println("打印中")
   }()
   defer func() {
      fmt.Println("打印后")
   }()
   panic("触发异常")
}
//以上代码执行顺序是不一定的,
//defer函数属于延迟执行,就是执行到return之前执行,然后再return
//一般defer,panic,recover()配合使用来捕获异常。
//recover放在哪个函数中,panic就会在哪个函数中执行
//必须先声明defer,否则recover()不能捕获到异常
//如果多个defer都使用recover(),那个panic就是使用离它最近的recover()捕获并正常处理

代码修改后

第一种情况:
package main

import "fmt"

func main()  {
   defer_call()
}

func defer_call()  {
   defer func() {
      if err:=recover();err!=nil{ fmt.Println(err) //err就是panic  } fmt.Println("打印前") }() defer func() { fmt.Println("打印中") }() defer func() { fmt.Println("打印后") }() panic("触发异常") }
 执行结果:

把recover()放在执行前那段defer里了。所以打印 输出就在执行前的defer中执行的

第二种情况,recover()三个defer都放

package main

import "fmt"

func main()  {
    defer_call()
}

func defer_call()  {
    defer func() {
        if err:=recover();err!=nil{
            fmt.Println(err) //err就是panic
        }
        fmt.Println("打印前")
    }()
    defer func() {
    if err:=recover();err!=nil{
       fmt.Println(err) //err就是panic
    }
fmt.Println(
"打印中") }() defer func() {
    if err:=recover();err!=nil{
       fmt.Println(err) //err就是panic
    }
    fmt.Println("打印后") 
  }()
  panic(
"触发异常")
}

 

 

2. 以下代码有什么问题,说明原因

package main

import "fmt"

type student struct {
    Name string
    Age  int
}

func pase_student() map[string]*student {
    m := make(map[string]*student)
    stus := []student{
        {"zhou", 24},
        {"li", 23},
        {"wang", 22},
    }
    for i, _ := 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}
发现value都是一样的,这是因为19行的&stu是指针,地址都保持不变,所以每个遍历都是值拷贝,所以实际上
m[stu_Name]=%stu都是指向的是同一个地址,最终遍历后的值都是最后一个map的值,wang,22
应该改成
for i, _ := range stus {
        stu=stus[i]
        m[stu.Name] = &stu
    }
以上代码是将stus遍历的每个值进行拷贝,拷贝完后每个地址的值都不一样。
*/

以下是修改后的代码
package main

import "fmt"

type student struct { Name string Age int } func pase_student() map[string]*student { m := make(map[string]*student) stus := []student{ {"zhou", 24}, {"li", 23}, {"wang", 22}, } for i, _ := range stus { fmt.Println("111",stus) stu:=stus[i]//这里直接用key来取value赋值到stu变量中,这样stu的地址都是新的。 m[stu.Name] = &stu } return m } func main() { students := pase_student() fmt.Println(students) for k, v := range students { fmt.Printf("key=%s,value=%v\n", k, v) } }
 

 

转载于:https://www.cnblogs.com/xiaonu/p/8961477.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值