【问题标题】:Nil slice vs empty slice and nil value comparisonNil 切片与空切片和 nil 值比较
【发布时间】:2016-03-22 14:07:39
【问题描述】:

我已经阅读了一些关于零切片与空切片的文本。我相信我对它们之间的区别有一些基本的了解。

我的理解总结:var instance []Type 为 nil 切片,instance == nil 返回true;而instance:=[]Type{} 是空切片,instance != nil

但是这个特殊的例子仍然让我感到困惑。

请查看下面的链接以获取代码。我的问题是最后两个案例。 https://play.golang.org/p/udyHoOlSeP

假设我想比较两个切片,重命名类型和接口匹配等等。接收者可以是nil 的实例,即使它没有定义为按值复制;虽然参数是按值复制的,但似乎 只要参数不是无类型的,就不是零。

在最后两种情况下,接收者被识别为nil,而:= 正在处理参数,因此它变成了一个空切片。 (但other == nil 也报告错误......)我怎样才能解决这个问题以满足以下要求?

nilslice.Equals(nilslice) // -> true


此外,我尝试定义另一个与接口指针相比的接口,但失败了。编译器抱怨

cannot use p (type *AnotherNullable) as type *PointerComparable in argument to AnotherNullable(nil).Equals: *PointerComparable is pointer to interface, not interface https://play.golang.org/p/wYO1GKcBds

我该如何解决这个问题?

编辑:感谢@zippoxer 提供的所有见解。我学到了很多。我也希望新读者也不要忘记查看@zippoxer在答案中的评论!

【问题讨论】:

  • 我更新了我的答案来解决你的第一个问题:-)

标签: go


【解决方案1】:

首先,您不需要指向接口的指针。接口已经是一个指针。 见Go: What's the meaning of interface{}?

只需将 Equals 方法更改为接受 PointerComparable 而不是 *PointerComparable。 Equals 将接受接口而不是指向接口的指针,但您仍然可以将指针传递给切片/任何内容。 见https://play.golang.org/p/e_Gtq2oAFA

其次,接收者Nullable 不是接口,而您传递给 Equals 的参数是接口。这可以解释为什么Nullable 接收器保持为零,而Comparable 参数不为零,尽管它的底层切片是。问题是,Comparable 参数是一个指向某个东西的接口,所以无论它指向什么,它都不会是 nil。

这段代码解释了问题:

var a interface{}
fmt.Println(a == nil) // true, the interface doesn't point to anything
var someNilSlice []int
fmt.Println(someNilSlice == nil) // true, just some nil slice
a = someNilSlice
fmt.Println(a == nil) // false, now the interface does point to something

【讨论】:

  • 非常感谢。这说明了很多。如果你要履行nilslice.Equals(nilslice) -> true,而不是试图变得有点通用并每次都去具体实施,你能建议你怎么做吗?
  • 我会先比较两个切片的长度。如果len(a)==len(b),它们都是空切片或零切片。如果您必须知道接口参数是否为 nil 而不仅仅是空,请尝试将其转换回原来的切片,然后进行比较。例如,other.(Nullable) == nil
  • @nilbot 你正在深入挖掘 Go 的类型系统。老实说,在你提出这些问题之前,我从来没有想过这些问题,太好了 ;-)
猜你喜欢
  • 2017-11-02
  • 1970-01-01
  • 2014-07-15
  • 1970-01-01
  • 2021-09-29
  • 2016-11-19
  • 2018-10-31
  • 1970-01-01
  • 2019-03-20
相关资源
最近更新 更多