指向切片和数组的指针

huangapple go评论98阅读模式
英文:

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 index x and the type of a[x] is the element type of A

> 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 index x and the type of a[x] is the element type of S

huangapple
  • 本文由 发表于 2016年3月27日 07:16:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/36242018.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定