为什么Go里值为nil可以调用函数原理分析

 更新时间:2023年08月07日 08:56:27   作者:煎鱼  
这篇文章主要为大家介绍了为什么Go里值为nil可以调用函数原理分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

起因

最近在我们 Go 的技术交流群里,有一个小伙伴提了一个程序方面的问题,还挺有意思的,分享给大家。

示例

示例程序如下:

type T struct{}
func (t *T) Hello() string {
    if t == nil {
        fmt.Println("脑子进煎鱼了")
        return ""
    }
    return "煎鱼进脑子了"
}
func main() {
    var t *T
    t.Hello()

这段程序的运行结果是什么?

从程序的分析来看,变量 t 并没有初始化,只是声明了类型。然后就直接调用了 Hello 方法,像是 nil 调用函数,理论上应该出现恐慌(panic)。

运行结果是:

panic: runtime error: invalid memory address or nil pointer dereference

对不对呢?

显然,真正的运行结果是:

脑子进煎鱼了

请你思考一下,想想这是为什么?

原理

问题的原因是:很多小伙伴认为变量 t 的值都是 nil 了,不应该还能调用到才对。

更抽象化来讲,就是 ”程序是如何检查对象指针来寻找和调度所需函数“。

实际上,在 Go 中,表达式 Expression.Name 的语法,所调用的函数完全由 Expression 的类型决定。

其调用函数的指向不是由该表达式的特定运行时值来决定,包括我们前面所提到的 nil。

具体如下:

func (p *Sometype) Somemethod (firstArg int) {}

本质上是:

func SometypeSomemethod(p *Sometype, firstArg int) {}

这么一看,其实大家应该都明白了。

上述入参 p *Sometype 是有具体上下文类型的,自然而然也就能调用到相应的方法。如果是没有任何上下文类型的,例如:nil.Somemethod 方法来调用,那肯定就是无法运行的。

与值是不是 nil,是什么,没有太多直接的影响。只要有预期类型的上下文就可以了。

总结

今天给大家分享了一个 Go 语言里面的一个小细节,平时可能很多人没注意到,毕竟 IDE 也会标黄,会避开这个问题点。

在理解 Go 的设计和思考上,我们是需要清晰其背后的原因和逻辑的,也就是类型决定其调用,而不是值(容易误判)。

以上就是为什么Go里值为nil可以调用函数原理分析的详细内容,更多关于Go值nil调用函数的资料请关注脚本之家其它相关文章!

相关文章

  • 使用Go实现健壮的内存型缓存的方法

    使用Go实现健壮的内存型缓存的方法

    这篇文章主要介绍了使用Go实现健壮的内存型缓存,本文比较了字节缓存和结构体缓存的优劣势,介绍了缓存穿透、缓存错误、缓存预热、缓存传输、故障转移、缓存淘汰等问题,并对一些常见的缓存库进行了基准测试,需要的朋友可以参考下
    2022-05-05
  • GO中优雅编码与降低圈复杂度详析

    GO中优雅编码与降低圈复杂度详析

    Go语法简单易用,有其他编程经验的开发者,相信学习并快速上手Go语言的开发,多数觉得不困难吧,下面这篇文章主要给大家介绍了关于GO中优雅编码与降低圈复杂度的相关资料,需要的朋友可以参考下
    2022-12-12
  • golang 定时任务方面time.Sleep和time.Tick的优劣对比分析

    golang 定时任务方面time.Sleep和time.Tick的优劣对比分析

    这篇文章主要介绍了golang 定时任务方面time.Sleep和time.Tick的优劣对比分析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • SingleFlight模式的Go并发编程学习

    SingleFlight模式的Go并发编程学习

    这篇文章主要为大家介绍了SingleFlight模式的Go并发编程学习,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • 使用Go Validator有效验证数据示例分析

    使用Go Validator有效验证数据示例分析

    作为一名开发者,确保Go应用中处理的数据是有效和准确的非常重要,Go Validator是一个开源的数据验证库,为Go结构体提供强大且易于使用的数据验证功能,本篇文章将介绍Go Validator库的主要特点以及如何在Go应用中使用它来有效验证数据
    2023-12-12
  • Golang使用gofumpt进行代码格式化

    Golang使用gofumpt进行代码格式化

    这篇文章主要为大家详细介绍了Golang如何使用gofumpt进行代码格式化,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-02-02
  • go mod tidy报错解决方法详解

    go mod tidy报错解决方法详解

    这篇文章主要为大家介绍了go mod tidy报错解决方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • go的defer和闭包示例说明(非内部实现)

    go的defer和闭包示例说明(非内部实现)

    这篇文章主要为大家介绍了go的defer和闭包示例说明(非内部实现),有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Go微服务网关的实现

    Go微服务网关的实现

    本文主要介绍了Go微服务网关的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 详解如何使用unsafe标准库突破Golang中的类型限制

    详解如何使用unsafe标准库突破Golang中的类型限制

    在使用c语言编程时,常常因为类型的问题大伤脑筋,而,golang提供了一些方式用于喜欢hack的用户,下面我们就来讲讲如何使用unsafe标准库突破Golang中的类型限制吧
    2024-03-03

最新评论