0

Go bits: Interfaces and Nil Pointers

 2 years ago
source link: https://medium.com/@TonyBologni/go-bits-interfaces-and-nil-pointers-7eeee006118e
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Go bits: Interfaces and Nil Pointers

Different types of nil in Go and how to check against them

Go has interfaces, pointer types, and sadly also nil pointers.

Trying to access properties of nil types results in a runtime panic, in other words, the program dies:

Therefore, sensible code needs to check for those nil pointers.

The situation gets a bit more complicated once interfaces are involved because now there are three possible types of nil:

  • nil pointer types
  • nil interfaces
  • interfaces with an underlying nil pointer type

A simple example

We need an interface:

and a pointer type implementing this interface:

I’ll use tests to be able to run the code easily (real tests should have assertions for sure …):

As we can see those

blocks check for nil and only access the CommandType() getter method if the command is not nil.

The problem appears in the last test case with the interfaceWithUnderlyingNilPointer

The interface itself is not nil as it is a typed interface — hence we run into a runtime panic when we dereference the underlying nil pointer.

A more realistic example

Let’s define another command type that fulfills the interface:

And a Command Handler which handles all those Commands:

As we can see the type switch turns the interface type into the underlying types — the implementations of the Command interface.

This is how we can check if the underlying type of an interface is a nil pointer — by casting it to the concrete type!

So far, so good. But we need to do the same nil pointer checks over and over, for each concrete Command.

We could use reflection to avoid those duplicate checks. But 1) reflection should be used sparingly and 2) each method should check its input instead of blindly trusting the caller (this is opinionated).

Finally, a test that proves we catch all types of nil here:

The second assertion in each test proves that we get back the expected error — either “command is nil interface” or “command is nil pointer”.

Additionally, the second test case shows that we can even pass untyped nil to a function. Go’s type inference turns it into a typed interface with a nil value.

I need to add that when the command arrives in the Handle() method we get the same type of thing in test cases three and four. That’s type inference in action again, which turns the nilCommand into an interfaceWithUnderlyingNilPointer. I just added test case four to show it explicitly.

I have stopped using pointer types for anything that is a data type and not a service (handler, repository, …). Not only but also to avoid this nil pointer trouble. No matter if you do the same or keep using pointer types for everything — I hope this article helps to avoid the nil pointer behind an interface pitfall. :-)

If you like this article — please don’t forget to clap or even follow me! :-)


Recommend

  • 28
    • studygolang.com 6 years ago
    • Cache

    Golang 关于 nil 的认识

    Golang 关于 nil 的认识 1. 什么是 nil ? 大家都清楚,当你声明了一个变量 但却还并木优赋值时,golang中会自动给你的变量类型给一个对应的默认零值。这是每种类型对应的零值: bool -> false...

  • 49
    • www.tuicool.com 6 years ago
    • Cache

    The nil value in Ruby

    The nil value in Ruby In this article we’re going to explore the following topics:...

  • 25
    • studygolang.com 5 years ago
    • Cache

    深入理解nil

    9.2 深入理解nil nil 是Go中熟悉且重要的预先声明的标识符。它是多种类型零值的字面表示。许多具有其他一些流行语言经验的新Go程序员可能会将其 nil 视为 null (或 NULL

  • 53
    • www.tuicool.com 4 years ago
    • Cache

    golang when is nil not nil

    在开发中,我们经常会遇到一个nil值不等于nil,先看一下下面这个例子 type itest struct { a string } func printA() *itest{ return nil } func main() { var i interface{} = printA() fmt.Printf("i is nil...

  • 29
    • studygolang.com 3 years ago
    • Cache

    【golang】nil的理解

    最近在油管上面看了一个视频:Understanding nil,挺有意思,这篇文章就对视频做一个归纳总结,代码示例都是来自于视频。 nil是什么 相信写过Golang的程序员对下面一段代码是非常非常熟悉的了: if err !=...

  • 10
    • nshipster.com 3 years ago
    • Cache

    nil / Nil / NULL / NSNull

    nil / Nil / NULL / NSNull Written by Mattt

  • 13
    • yourbasic.org 3 years ago
    • Cache

    Assignment to entry in nil map

    Assignment to entry in nil map yourbasic.org/golang Why does this program panic? var m map[string]f...

  • 35

    Invalid memory address or nil pointer dereference yourbasic.org/golang Why does this program panic? typ...

  • 14

    Differences Between #nil?, #empty?, #blank?, and #present? Joyce Echessa on Sep 11, 2018 “I absolutely love AppSignal.” Discover AppSi...

  • 9

    Interfaces and Nil in Go, or, Don't Lie to Computers Interfaces and Nil in Go, or, Don't Lie to Computers posted May 11, 2021 in Programming,

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK