我正在查看golang的堆包(https://golang.org/pkg/container/heap/)Priority Queue示例,并且遇到了这个:
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
}
Run Code Online (Sandbox Code Playgroud)
当我开始玩这个代码以确保我理解它时,我试过:
item := *pq[0] // error
Run Code Online (Sandbox Code Playgroud)
这给你类型*[] T不支持索引.但如果你这样做:
item := (*pq)[0] // all is well
Run Code Online (Sandbox Code Playgroud)
这是类型断言吗?希望有人能解释这里发生的事情.
以下是一些快速显示的代码:https://play.golang.org/p/uAzYASrm_Q
对你有用的不是类型断言 - 它是操作顺序.
问题的根源在于索引在指针解除引用之前.一旦你在指针解除引用周围放置大括号,它一切正常,因为索引应用于现在解除引用的PriorityQueue实例.
您不需要为数组指针执行此操作,因为它们会自动解除引用 - 索引数组和切片之间的细微差别在此解释:Go编程语言规范 - 索引表达式
对于
a数组类型A:
- 常量索引必须在范围内
- 如果
x在运行时超出范围,则会发生运行时混乱a[x]是索引处的数组元素,x类型a[x]是元素类型A对于
a指向数组类型的指针:
a[x]是简写(*a)[x]对于
a切片类型S:
- 如果
x在运行时超出范围,则会发生运行时混乱a[x]是索引处的切片元素,x类型a[x]是元素类型S