浅谈Go与习题(二十五)

107 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情

今天来学习下Go常见的习题问题(二十五),也是面试中可能会遇到的,让我们来一起学习吧~

逃逸分析

观察下列代码,判断变量p是否会因为函数结束而释放?

type TimesMatcher struct {
    base int
}

func NewTimesMatcher(base int) *TimesMatcher  {
    return &TimesMatcher{base:base}
}

func main() {
    p := NewTimesMatcher(10)
    fmt.Println(p)
}

参考答案:不会被释放,因为根据Go语言中的内存回收机制gc,只要有一个指针引用赋值给一个变量,那么这个变量就不会被释放,这里发生了逃逸分析,因为当函数执行完毕,分配的栈内存就会被销毁,这块是有编译器负责分配和销毁,但是指针引用已经返回给变量p,那么外部函数通过变量p通过*p来取值,虽然地址存在但是内存已经被回收释放,就存在野指针的情况,所以会发生逃逸(顾名思义:把栈上内存分配到堆上),因此在 Go 语言中返回函数参数或临时变量是安全的

iota

观察下列代码,判断输出结果是什么?为什么?

const (
    azero = iota
    aone  = iota
)

const (
    info  = "msg"
    bzero = iota
    bone  = iota
)

func main() {
    fmt.Println(azero, aone)
    fmt.Println(bzero, bone)
}

参考答案:输出0 1 1 2,这里考察iota 的使用,在一个常量声明代码块中,iota出现在第一行初始值才为0,其他情况是根据所在行数判断

同级文件的包名不允许有多个

一个文件夹下只能有一个包,可以多个.go文件,但这些文件必须属于同一个包

接口

观察下列代码,判断是否通过编译?

type data struct {
    name string
}

func (p *data) print() {
    fmt.Println("name:", p.name)
}

type printer interface {
    print()
}

func main() {
    d1 := data{"one"}
    d1.print()

    var d2 printer = data{"two"}
    d2.print()
}

参考答案:不能通过编译,因为结构类型data{"two"}没有实现print()方法,需要使用var d2 printer = &data{"two"}才可以

总结

今天浅谈了Go的习题(二十五),主要介绍了GO面试中会出现的问题,接下来会继续分享其他的习题的相关知识,对于一个刚入门的我来说,还有许多地方需要学习,有错误的地方欢迎大家指出,共同进步!!