Golang指向切片和数组的指针

时间:2016-03-26 23:16:28

标签: arrays go slice

我正在查看golang的堆包(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 // for safety
    *pq = old[0 : n-1]
    return item
} 

当我开始使用此代码以确保我理解它时,我尝试了:

item := *pq[0] // error

这为您提供类型* [] T不支持索引。但如果你这样做:

item := (*pq)[0] // all is well

这是类型断言吗?希望有人能解释这里发生的事情。

以下是一些快速显示此代码的代码:https://play.golang.org/p/uAzYASrm_Q

1 个答案:

答案 0 :(得分:7)

对你有用的不是类型断言 - 它是操作顺序。

问题的根源在于索引在指针解除引用之前。一旦你在指针解除引用周围放置大括号,一切都运行良好,因为索引应用于现在解除引用的PriorityQueue实例。

您不需要为数组指针执行此操作,因为它们会自动解除引用 - 索引数组和切片之间的细微差别在此处说明:The Go Programming Language Specification - Index expressions

  

对于数组类型a的{​​{1}}:

     
      
  • 常量索引必须在范围
  •   
  • 如果A在运行时超出范围,则会发生运行时恐慌
  •   
  • x是索引a[x]的数组元素,x的类型是a[x]的元素类型
  •   
     

对于A指向数组类型的指针:

     
      
  • aa[x]
  • 的简写   
     

对于(*a)[x]切片类型的a

     
      
  • 如果S在运行时超出范围,则会发生运行时恐慌
  •   
  • x是索引a[x]的切片元素,x的类型是a[x]的元素类型
  •