go 函数返回值的类型会自动初始化?

直接看代码

package test

import (
    "fmt"
    "testing"
)

type StructA struct {
    str string
}

func NewStructA() *StructA {
    return nil
}

type InterfaceA interface{}

func ToInterfaceA() InterfaceA {
    return NewStructA() //  NewStructA return nil
}
func ReturnInterface() InterfaceA {
    return nil
}

func TestXXX(t *testing.T) {
    a := ReturnInterface()
    fmt.Println(a == nil)           // true
    fmt.Printf("type of a %T\n", a) // type of a <nil>

    b := NewStructA()
    fmt.Println(b == nil)           // true
    fmt.Printf("type of b %T\n", b) // type of b *test.StructA

    c := ToInterfaceA()
    fmt.Println(c == nil)           // false
    fmt.Printf("type of c %T\n", c) // type of c *test.StructA
}

为什么 c == nil 是false?

阅读 4.3k
3 个回答

Interface类型由value和type两部分组成,。type是接口的基础具体类型,value是具体类型的值:

  • a是Interface类型,ReturnInterface函数直接返回nil是符合要求的,最后比较 a == nil,也是可以看成同类型比较的,值也相同,比较结果为true。
  • b是指针类型,默认值为nil,NewStructA直接返回nil是符合要求的,最后比较 b == nil,也是可以看成同类型比较的,值也是相同的,比较结果为true。
  • c是Interface类型,但是ToInterfaceA中的NewStructA()的返回结果是一个指针类型,不过值为nil,最后得到的c其实类型是指针,值为nil的interface,nil可以看做类型和值都是nil的interface,所以两个比较结果是false。

认为c是Interface类型的依据:
Go中认为实现了一个接口就是拥有这个接口的所有函数,这个程序中InterfaceA接口是一个空的接口,没有函数,所以所有类型都实现了这个接口,当然也包括指针,所以在ToInterfaceA的返回值才没有报错。如果认为ToInterfaceA函数返回的一个指针类型的话,可以在InterfaceA中增加一个Name函数,StructA不实现这个函数的话,程序是会报错的。

clipboard.png

(目前也在学习GO,错了的话,嗯~~~~请谅解。)

c是一个interface类型,在interface类型内由type和value两部分组成。而c的type类型为*StructA,所以它其实不为nil,因为它内部实际存储了类型信息了。

换一个写法

var b *StructA
var c InterfaceA

使用"%T"的时候,c输出的不是InterfaceA,而是*StructA也说明了这一点

除了赋值 nil 给接口,接口永远不等于 nil

举例

var s *MyStruct
var i MyInterface
// 此时 i == nil

// 若赋值任何结构指针
i = s
// 此时 i != nil
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题