英文:
Pointer to slice and array
问题
我正在查看Go语言的堆包(https://golang.org/pkg/container/heap/)中的优先队列示例,并遇到了以下代码:
type PriorityQueue []*Item
...
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
item.index = -1 // 为了安全起见
*pq = old[0 : n-1]
return item
}
当我开始尝试修改这段代码以确保我理解它时,我尝试了以下代码:
item := *pq[0] // 错误
这会导致出现"type *[]T does not support indexing"的错误。但是,如果你这样做:
item := (*pq)[0] // 一切正常
这是类型断言吗?希望有人能解释一下这里发生了什么。
这里有一些代码可以快速展示这个问题:https://play.golang.org/p/uAzYASrm_Q
英文:
I was looking at Go's heap package's (https://golang.org/pkg/container/heap/) Priority Queue example and came across this:
type PriorityQueue []*Item
...
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
item.index = -1 // for safety
*pq = old[0 : n-1]
return item
}
When I started playing around with this code to make sure I understood it, I tried:
item := *pq[0] // error
This gives you type *[]T does not support indexing. But if you do:
item := (*pq)[0] // all is well
This is type assertion right? Was hoping someone could explain what is going on here.
Here is some code to quickly show this: https://play.golang.org/p/uAzYASrm_Q
答案1
得分: 10
对你有效的不是类型断言,而是操作顺序。
问题根源在于索引操作在解引用指针之前进行。一旦在指针解引用周围加上大括号,一切都能正常工作,因为索引操作应用于现在已解引用的PriorityQueue
实例。
对于数组指针,你不需要这样做,因为它们会自动解引用。数组和切片之间的细微差别在这里有解释:Go编程语言规范-索引表达式
-
对于类型为
A
的数组a
:- 常量索引必须在范围内
- 如果
x
在运行时超出范围,会发生运行时恐慌 a[x]
是索引为x
的数组元素,a[x]
的类型是A
的元素类型
-
对于指向数组类型的指针
a
:a[x]
是(*a)[x]
的简写
-
对于类型为
S
的切片a
:- 如果
x
在运行时超出范围,会发生运行时恐慌 a[x]
是索引为x
的切片元素,a[x]
的类型是S
的元素类型
- 如果
英文:
What works for you is not type assertion - it's operation ordering.
The problem is rooted in the fact that the indexing precedes the dereferencing of your pointer. Once you put braces around the pointer dereferencing, it all works well, because the indexing is applied to the now dereferenced PriorityQueue
instance.
You don't need to do that for array pointers, because they are automatically dereferenced - the slight difference between indexing arrays and slices is explained here: The Go Programming Language Specification - Index expressions
> For a
of array type A
:
>- a constant index must be in range
- if
x
is out of range at run time, a run-time panic occurs a[x]
is the array element at indexx
and the type ofa[x]
is the element type ofA
> For a
of pointer to array type:
> - a[x]
is shorthand for (*a)[x]
> For a
of slice type S
:
> - if x
is out of range at run time, a run-time panic occurs
-
a[x]
is the slice element at indexx
and the type ofa[x]
is the element type ofS
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论