美文网首页
理解interface和nil

理解interface和nil

作者: bysir | 来源:发表于2018-03-25 00:28 被阅读0次

    判断一下以下代码会打印什么?

    package main
    
    import (
        "fmt"
    )
    
    type MyError struct{}
    
    func (e *MyError ) Error() string {
      return "a"
    }
    
    
    
    func main() {
        var a *MyError
        if a == nil {
            fmt.Println("a == nil")
        } else {
            fmt.Println("a != nil")
        }
        fmt.Println("a Error():", a.Error())
    
        var b error = a
        if b == nil {
            fmt.Println("b == nil")
        } else {
            fmt.Println("b != nil")
        }
        fmt.Println("b Error():", b.Error())
    }
    

    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .
    .

    会打印出

    a == nil
    a Error(): a
    b != nil
    b Error(): a
    

    和你预期是否一致呢? 试着理解一下这个问题.

    ---- 分割线 ----

    在底层,interface作为两个成员实现:一个类型和一个值。该值被称为接口的动态值, 它是一个任意的具体值,而该接口的类型则为该值的类型。对于 int 值3, 一个接口值示意性地包含(int, 3)。

    只有在内部值和类型都未设置时(nil, nil),一个接口的值才为 nil。

    在以上代码中b存储的是(*MyError, nil), 因此,b是非 nil 的,即使在该指针的内部值为 nil。

    实践

    此问题并不出现在面试题中, 在日常封装接口(大多是自定义error才会用==nil的判断)时, 就要注意此问题, 如下面两种写法:

    type MyError struct{}
    
    func (e *MyError ) Error() string {
      return "a"
    }
    
    // good
    func NewError(msg string) error{
      if (msg==""){
        return nil
      }
      return &MyError{}
    }
    
    
    // bad
    func NewError(msg string) *MyError{
      if (msg==""){
        return nil
      }
      return &MyError{}
    }
    

    其中bad写法就会导致err == nil 为false

    var err error
    err = NewError("")
    print(err == nil) // false
    

    参考

    相关文章

      网友评论

          本文标题:理解interface和nil

          本文链接:https://www.haomeiwen.com/subject/zzhpqftx.html