为了账号安全,请及时绑定邮箱和手机立即绑定

标准库优先级队列推送方法

标准库优先级队列推送方法

Go
ITMISS 2021-05-05 13:12:12
下面的代码段是优先级队列的push方法的库实现。我想知道为什么代码行a = a[0 : n+1]不会引发超出范围的错误。 func (pq *PriorityQueue) Push(x interface{}) {    // Push and Pop use pointer receivers because they modify the slice's length,    // not just its contents.    // To simplify indexing expressions in these methods, we save a copy of the    // slice object. We could instead write (*pq)[i].    a := *pq    n := len(a)    a = a[0 : n+1]    item := x.(*Item)    item.index = n    a[n] = item    *pq = a}
查看完整描述

3 回答

?
森栏

TA贡献1810条经验 获得超5个赞

切片不是数组;它是现有阵列的视图。有问题的切片由大于其自身的数组支持。在定义现有切片的切片时,实际上是在切片基础数组,但是引用的索引是相对于源切片的。


满嘴 让我们以以下方式证明这一点:我们将创建一个零长度的切片,但是我们将强制底层数组更大。使用创建切片时make,第三个参数将设置基础数组的大小。该表达式make([]int, 0, 2)将分配大小为 2 的数组,但计算结果为大小为零的切片。


package main


import ("fmt")


func main() {

    // create a zero-width slice over an initial array of size 2

    a := make([]int, 0, 2)

    fmt.Println(a)


    // expand the slice.  Since we're not beyond the size of the initial

    // array, this isn't out of bounds.

    a = a[0:len(a)+1]


    a[0] = 1

    fmt.Println(a)

    fmt.Println(a[0:len(a)+1])

}

看这里。您可以使用cap关键字来引用支持给定切片的数组的大小。


您询问的特定代码cap(pq)在调用上下文中循环(container / heap / example_test.go 90行)。如果您在调用站点上修改了代码并尝试将另一个项目推送到队列中,它将如您所愿地惊慌。我...可能不会建议编写这样的代码。尽管标准库中的代码可以执行,但是如果在我的代码库中发现该代码,我会感到很酸。通常,使用append关键字更安全。


查看完整回答
反对 回复 2021-05-31
?
倚天杖

TA贡献1828条经验 获得超3个赞

因为它可以在特定的示例程序中使用。这是原始/完整示例源中的重要部分)


const nItem = 10


pq := make(PriorityQueue, 0, nItem)


for i := 0; i < cap(pq); i++ {

        item := &Item{

                value:    values[i],

                priority: priorities[i],

        }

        heap.Push(&pq, item)

}


查看完整回答
反对 回复 2021-05-31
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

总的来说,它确实如此。它不在container/heap示例中。这是我前一段时间给您的一般修复方法。


func (pq *PriorityQueue) Push(x interface{}) {

    a := *pq

    n := len(a)

    item := x.(*Item)

    item.index = n

    a = append(a, item)

    *pq = a

}


查看完整回答
反对 回复 2021-05-31
  • 3 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信