Standard Queue Queue Method

The code snippet below is an implementation of the push method library for the priority queue. I am wondering why the line with the code a = a[0 : n+1] does not throw errors outside the bounds.

  func (pq *PriorityQueue) Push(x interface{}) { // Push and Pop use pointer receivers because they modify the slice 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 } 
+4
source share
4 answers

a slice is not an array; this is a view of an existing array. This slice is backed up by an array larger than himself. When you define a fragment of an existing slice, you are actually slicing the base array, but the indicated indices refer to the original slice.

This is a sip. We prove this as follows: we will create a slice of zero length, but we will make the main array be larger. When creating a slice with make third parameter sets the size of the base array. The expression make([]int, 0, 2) will select an array of size 2, but it is evaluated as a slice with a zero size.

 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]) } 

see here . You can use the cap keyword to refer to the size of the array that this slice supports.

The specific code you requested about loops over cap(pq) in the calling context (container / heap / example_test.go, line 90). If you change the code on the call site and try to click another item in the queue, it will panic as you expect. I ... probably wouldn't suggest writing such code. Although the code in the standard library executes, I would be very sour if I found this in my code base. It is generally safer to use the append keyword.

+3
source

Because it works in a specific sample program. Here are the important parts of the original / complete)

 const nItem = 10 

and

 pq := make(PriorityQueue, 0, nItem) 

and

 for i := 0; i < cap(pq); i++ { item := &Item{ value: values[i], priority: priorities[i], } heap.Push(&pq, item) } 
+2
source

Is this an example from container / heap ? If yes, then this throws an exception, since the capacity is quite large (see. Method of using the Push method). If you change the example to Push more items, then capacity, and then it will be selected.

+1
source

It is generally; this is not in the container/heap example. Here's a general fix that I already gave you some time ago.

 func (pq *PriorityQueue) Push(x interface{}) { a := *pq n := len(a) item := x.(*Item) item.index = n a = append(a, item) *pq = a } 

Golang solution for Project Euler # 81 problem

0
source

All Articles