当前位置: 首页 > 知识库问答 >
问题:

Nil切片与空切片以及Nil值比较

浦德明
2023-03-14

我读过一些关于零片和空片的文章。我相信我对他们之间的差异有一些基本的了解。

我的理解总结:var实例[]Type是nil片和实例==nil返回true;而实例:=[]Type{}是空片和实例!=nil

然而,这个特殊的例子仍然困扰着我。

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

假设我想比较两个片段,重命名类型和接口匹配以及所有。接收机可以是nil,即使未定义为按值复制;虽然参数是按值复制的,但只要参数不是非类型化的,它似乎是非nil的。

在最后两种情况下,当参数由:=处理时,接收方被标识为nil,因此它成为一个空片。(但是other==nil也报告false…)如何解决此问题以满足以下要求?

nilsice。等于(nilsicle)//-

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

不能将p(type*AnotherNullable)作为类型*指针在参数中与AnotherNullable(nil)进行比较。等于:*PointerCompable是指向接口的指针,而不是接口的指针https://play.golang.org/p/wYO1GKcBds

我怎样才能解决这个问题?

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


共有1个答案

戚正业
2023-03-14

首先,您不需要指向接口的指针。接口已经是指针了。参见Go:接口{}的含义是什么?

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

其次,接收器Nullable不是接口,而传递给Equals的参数是接口。这就解释了为什么Nullable接收器保持为nil,而可比参数不是nil,尽管它的基础切片是。问题是,可比参数是一个指向某个东西的接口,所以无论它指向什么,它都不会是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
 类似资料:
  • 我是一个编程新手。我在go编程书中读到过,片由三部分组成:指向数组的指针、长度和容量。 我感到困惑的零切片(切片没有底层数组指向,len=0,cap=0),非零切片只有len=0,cap=0和空切片。 谁能告诉我零和空切片是否是一回事?如果它们都不同,那么请告诉这两者之间的区别是什么? 如何测试一个切片是否为空? 另外,指针在长度和容量为零的非nil片中保留什么值?

  • 问题内容: 我是Go编程的新手。我已经阅读了Go编程书籍,其中的内容由三部分组成:指向数组的指针,长度和容量。 我对nil slices(切片没有指向len的下层数组,len = 0,cap = 0),非lens切片(其中只有len = 0,cap = 0)和空切片之间感到困惑。 谁能告诉我nil和空片是否相同?如果两者都不相同,那么请说出两者之间的区别是什么? 如何测试切片是否为空? 另外,指针

  • 问题内容: 我按照示例https://tour.golang.org/moretypes/10 进行了修改,希望得到相同的结果。我没有。这是错误还是文档错误?巡回演出 无切片的长度和容量为0。 我的y变量的长度和容量为0。 这是我的输出。 我期待第二个“零”〜我为什么不明白呢? 问题答案: 您参考的文档指出 零个切片的长度和容量为0, 但并非 每个 长度和容量为零的切片都是零个切片。规范仅说 未初

  • 问题内容: 我很好奇拆包切片并将其作为参数发送给可变参数函数。 假设我们有一个带有可变参数的函数: 如果我们不想传入一个接口,它就可以工作,那么我们是否拆包都没关系: 如果我们有一片片的话,那会很棘手。在这里,编译器不允许我们传递解压版本: 错误提示: 在解包参数中不能将sliceOfSlices(类型[] [] interface {})用作类型[] interface {} 我不知道为什么会这

  • 取一个list或tuple的部分元素是非常常见的操作。比如,一个list如下: >>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] 取前3个元素,应该怎么做? 笨办法: >>> [L[0], L[1], L[2]] ['Michael', 'Sarah', 'Tracy'] 之所以是笨办法是因为扩展一下,取前N个元素就没辙了。 取前N个元素

  • 举个例子 给你一个list 让你取前30个怎么办? a = [] # 很多数据 a[0],a[1] #按照这种方式吗?这也太复杂了! for i in a: pass ## 这种方式也是可以的,但是还是有点复杂了,在编程语言中,或者是我们的编程思想中,less is more是最重要的,也就是说,写的越少越好。 # 所以我们可以采用切片的方式 a[1:3],从第二个开始到第