3 回答

TA贡献1825条经验 获得超4个赞
接口值是一个简单的数据结构,由两部分组成:类型和基础值。因此,接口值本身可以是 ,或者接口值可以存在,但基础值可以是 。例如:nilnil
var x interface{} = nil // x is nil
var y interface{} = (interface{})(nil) // y is a interface{}, which *contains* nil
这在某些概念上与此差异相似:
var x []*int = nil // x is nil
var y []*int = []*int{nil} // y is a []*int, which *contains* nil
fmt.Printf由于接口格式化输出的方式,掩盖了接口情况下的差异;如果您愿意,可以使用反射更清楚地看到差异。

TA贡献1873条经验 获得超9个赞
在 Go 中,引用某些接口的实现者的变量可以具有多种类型。它可以是类型(是的,可以描述类型以及值),它可以是其实现者之一的类型,也可以是指向其实现者之一的指针的类型。默认情况下,引用接口的变量的类型为 。一旦你向它分配了一些东西(除了它本身),它就会采用你分配给它的东西的类型(同样,要么是它的实现者之一的类型,要么是指向其中一种类型的指针)。<nil>nilnilnil
可以使用 打印接口变量的类型,并使用 %v 打印其值:%T
func main() {
var i SomeInterface
fmt.Printf("%T, %v\n", i, i) // Prints <nil>, <nil>
var someStruct SomeStruct
i = someStruct
fmt.Printf("%T, %v\n", i, i) // Prints main.SomeStruct, {}
var someStructPtr *SomeStruct
i = someStructPtr
fmt.Printf("%T, %v\n", i, i) // Prints *main.SomeStruct, <nil>
}
现在,每当您比较时,只有当两个操作数的类型和值都匹配时,比较才会被计算为 true。在你的情况下,的值显然是(毕竟,的值肯定是 ,并且你将其值存储在 中)。的类型,根据我刚才解释的内容,必须是 。的价值显然是。h.SomeObject == nilh.SomeObject<nil>someStruct<nil>h.SomeObjecth.SomeObject*SomeStructnil<nil>
但是,是什么类型?nil
好吧,可以采用多种类型,编译器必须决定每种用法应该采用哪种类型。当涉及到比较和分配时,它只是简单地采用它被比较或分配的东西的类型。例如,如果要将整数指针与 进行比较,则在这种情况下,类型为 。nilnilnil*int
但所有这些都必须在编译时决定,并且引用接口的变量可以在运行时更改类型。那么,当您将引用接口的变量与 进行比较时,在这种情况下,编译器会为操作数提供什么类型呢?好吧,它给了它唯一合理的类型, .nilnil<nil>
最后一个示例,请考虑以下代码:
func main() {
var p *SomeStruct = nil // = nil is optional; pointers default to nil
var i SomeInterface = p
printf("%t\n", p == nil) // Prints true
printf("%t\n", p == i) // Prints true
printf("%t\n", i == nil) // Prints false
}
p == nil为 true,因为 is 的类型带有值 ,并且(在本例中)也是具有值的类型。p*SomeStruct<nil>nil*SomeStruct<nil>
p == i是 true,因为 也是具有值的类型(它只是存储 的类型和值)。i*SomeStruct<nil>p
但是,是 false,因为在这种情况下,采用的类型而不是 。i == nilnil<nil>*SomeStruct
解决这个问题的方法是永远不要在接口引用变量中存储一些有价值的东西,除了它本身。这样,每当接口引用变量的值为 时,其类型也将是 ,并且比较将按预期工作。因此,您经常会看到如下所示的代码:<nil>nil<nil><nil>nil
if p == nil {
i = nil
} else {
i = p
}

TA贡献1847条经验 获得超7个赞
SomeObject 不是 nil,它只是指向 SomeStruct,它是 nil。
我认为混乱是fmt。Printf打印这种情况,因为它遵循指针,最终结果是零。<nil>
- 3 回答
- 0 关注
- 157 浏览
添加回答
举报