Golang:针对nil类型的防御性接口

huangapple go评论82阅读模式
英文:

Golang: Defensive interfaces for nil types

问题

最近我发现一些 Go 代码在一个测试框架中运行时存在一些未初始化的变量。

这导致了一个 panic,其中的堆栈跟踪在顶部包含了一些 C 代码。

在函数中,有没有一种简洁的方法可以检测被引用为实现成员的结构体是否为 nil?例如:

func (d *Dog) canBark() bool {
      // 如果 d 是 nil,会抛出一个晦涩的异常。
      // 有没有一种方法可以防止这种情况发生?
}

抛出的错误信息是:

panic: runtime error: invalid memory address or nil pointer dereference 
[signal 0xb code=0x1 addr=0x0 pc=0x4ec83a] 
goroutine 16 [running]:   
runtime.panic(0x9b7400, 0xf7ddf3) 

在 Go 中,这种底层错误似乎应该很少发生,甚至可能根本不会发生...

可能有一种 Golang 的方式来处理不会在代码中过多使用 if/else 逻辑的 nil 引用。例如,在 Java 中,你可以在一个空指针异常处理程序中包装一个大的代码段。

英文:

I recently found some go code was running in a test framework where there were some uninitialized variables.

This lead to a panic, which had a stack trace containing some c code at the top.

Is there a way, in functions, that we can concisely detect wether the struct which is referenced as the implementing member is nil? i.e.

func ( d *Dog ) canBark Bool {
      //if d is nil, cryptic exception is thrown.
      //is there a way to defend against this?
}

The error which is thrown is

panic: runtime error: invalid memory address or nil pointer dereference 
[signal 0xb code=0x1 addr=0x0 pc=0x4ec83a] 
goroutine 16 [running]:   
runtime.panic(0x9b7400, 0xf7ddf3) 

It seems that in go, such lower level errors should occur very rarely, maybe never at all...

There might be a Golang way to deal with nil references which don't clutter the code too much with if/else logic. For example, in java, you can wrap a large code segment in a null pointer exception handler.

答案1

得分: 4

你可以检查是否为nil,然后执行相应的操作:

func (d *Dog) canBark() bool {
    if d == nil {
        // 做一些有用的事情,比如记录用于以后调试的堆栈跟踪
        log.Print("尝试让一个空的狗叫!")
        return false
    }
    // 执行常规操作
}

这段代码是一个示例,用于检查一个Dog对象是否为nil,如果是,则打印一条日志并返回false。否则,执行正常的操作。

英文:

You can check for nil and then do whatever:

func (d *Dog) canBark bool {
    if d == nil {
        // do something useful, maybe? Like log
        // a stack trace for debugging later
        log.Print("Attempt to bark a nil dog!")
        return false
    }
    // do the regular things
}

答案2

得分: 2

func (d *Dog) bool {
if d == nil {
// 一个空的狗不能叫
return false
}
}

在Go语言中,完全可以在空的结构体上使用方法。然而,对于空的接口来说就不同了。你无法防止这种情况发生,因为没有类型可以调用方法。

type Barker interface {
CanBark() bool
}

var dog Barker
// 报错
dog.CanBark()

在Go语言中,如果不正确地初始化数据结构,或者方法出现问题,都会导致编程错误。如果一个类型的值从函数或方法中返回给你,通常也会返回一个错误值,指示第一个值是否可以使用。

英文:

Sure:

func ( d *Dog ) bool {
    if d ==  nil {
        // a nil dog can't bark
        return false
    }
}

It's entirely possible to use methods on a nil struct. However, a nil interface is another story. You can't defend against that, because there's no type to call a method on.

type Barker interface {
	CanBark() bool
}

var dog Barker
//panics
dog.CanBark()

In go, it's a programming error to improperly initialize a data structure, and methods can panic. If a type value is returned to you from a function or a method, there is generally an error value returned as well indicating whether the first value can be used.

huangapple
  • 本文由 发表于 2015年4月9日 05:06:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/29525368.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定