英文:
Nil slice vs empty slice and nil value comparison
问题
我已经阅读了关于nil切片和空切片的一些文本。我相信我对它们之间的区别有一些基本的理解。
我对理解的总结是:var instance []Type
是一个nil切片,instance == nil
返回 true
;而 instance:=[]Type{}
是一个空切片,instance != nil
。
然而,这个特定的例子仍然让我感到困惑。
请查看下面的链接以获取代码。我的问题是最后两个例子。
https://play.golang.org/p/udyHoOlSeP
假设我想比较两个切片,包括类型和接口匹配等。在一个接收器可以是 nil
的情况下,即使它没有被定义为按值复制;而参数是按值复制的,似乎只要参数不是无类型的,接收器就不是 nil
。
在最后两个例子中,接收器被识别为 nil
,而参数正在被 :=
处理,所以它变成了一个空切片。(但是 other == nil
也报告为假...)我该如何修复这个问题以满足以下要求?
此外,我尝试定义另一个与接口指针进行比较的接口,但失败了。编译器报错:
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 的评论!
英文:
I have read some text regarding nil slice vs empty slice. I believe I have some basic understanding of the differences between them.
Summary of my understanding: var instance []Type
is nil slice and instance == nil
returns true
; while instance:=[]Type{}
is empty slice and instance != nil
However this particular instance still puzzles me.
Please look at the link below for code. My question is the last 2 cases.
https://play.golang.org/p/udyHoOlSeP
Suppose I want to compare two slices, renamed type and interface matching and all. The instance where a receiver can be nil
, even though it's not defined as copy by value; while the argument is copied by value, seems to
be non-nil as long as the argument is not untyped.
In the last 2 cases, receiver has been identified as nil
while argument is being processed by :=
so it becomes an empty slice. (But the other == nil
also reports false...) How can I fix this to satisfy the following requirement?
Further, I tried to define another interface comparing to pointers of interface but failed. Compiler complains that
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
How can I fix that?
EDIT: Thanks to @zippoxer for all the insights. I learned a lot. I hope new readers too, please don't forget to check out @zippoxer's comment in the answer too!
答案1
得分: 4
首先,你不需要一个指向接口的指针。接口本身就是一个指针。
参考链接:https://stackoverflow.com/questions/23148812/go-whats-the-meaning-of-interface/23148998#23148998
只需将Equals方法更改为接受PointerComparable
而不是*PointerComparable
。Equals将接受一个接口而不是接口的指针,但你仍然可以将指向切片/其他内容的指针传递给它。
参考链接:https://play.golang.org/p/e_Gtq2oAFA
其次,接收器Nullable
不是一个接口,而你传递给Equals的参数是一个接口。这就解释了为什么Nullable
接收器保持为nil,而Comparable
参数不是nil,尽管它的底层切片是nil。事实上,Comparable
参数是一个指向某个东西的接口,所以无论它指向什么,它都不会是nil。
以下代码解释了这个问题:
var a interface{}
fmt.Println(a == nil) // true,接口没有指向任何东西
var someNilSlice []int
fmt.Println(someNilSlice == nil) // true,只是一个空的切片
a = someNilSlice
fmt.Println(a == nil) // false,现在接口指向了某个东西
英文:
First, you don't need a pointer to an interface. An interface is already a pointer.
See https://stackoverflow.com/questions/23148812/go-whats-the-meaning-of-interface/23148998#23148998
Just change the Equals method to accept a PointerComparable
instead of a *PointerComparable
. Equals will accept an interface instead of a pointer to an interface, but you can still pass a pointer to a slice/whatever to it.
See https://play.golang.org/p/e_Gtq2oAFA
Second, the receiver Nullable
isn't an interface, while the argument you pass to Equals is an interface. That would explain why the Nullable
receiver stays nil and the Comparable
argument isn't nil although it's underlying slice is. The thing is, the Comparable
argument is an interface that points to something, so whatever it points to, it won't be nil.
This code explains the problem:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论