2017-01-07 1 views
1
package main 

import "fmt" 

type Point struct { 
     X int 
     Y int 
} 

type Points struct { 
    P []Point 
} 

func main() { 
    data := Points{} 
    for i := 0; i < 10; i++ { 
     data.P = append(data.P, Point{ 
      X: i, 
      Y: i*2, 
     }) 
    } 
    fmt.Printf("%+v\n", data.P[5:11]); 
} 

Хотя выше программа запущена, она распечатана:golang: Почему следующий код не паниковать с "индексом среза из диапазона" ошибка

[{X: 5 Y: 10} {X : 6 Y: 12} {X: 7 Y: 14} {X: 8 Y: 16} {X: 9 Y: 18} {X: 0 Y: 0}]

Почему существуют {X: 0 , Y: 0}, который, кажется, автоматически генерируется, поскольку длина среза равна 10, но я пытаюсь получить 5:11?

Я нашел проблему в моем коде и тесте с «сырой» срезе, такие как:

package main 

import "fmt" 

func main() { 
    v := []int{0,1,2,3,4,5,6,7,8,9} 
    fmt.Printf("%v\n", v[5:11]) 
} 

Эта простая программа генерирует ошибки (как и ожидалось):

panic: runtime error: slice bounds out of range 

goroutine 1 [running]: 
panic(0x47a8e0, 0xc42000a130) 
     /usr/local/go/src/runtime/panic.go:500 +0x1a1 
main.main() 
     /home/fxr/go/src/cmhwc/test2.go:7 +0x53 
exit status 2 

Почему первая программа делает не паника?

+1

Распечатайте емкость среза в каждой ситуации, и вы поймете, почему. – JimB

ответ

1

Потому что, когда вы используете append() для добавления элементов в срез, у которого нет больше места для добавления новых элементов, он создает новый, удваивая его емкость, копируя старые элементы, а также новое, которое вы просите добавить и возвращая ссылку на это. Далее, когда вы используете синтаксис среза для запроса элементов, прошедших через кажущийся конец среза, длина фактически применяется к базовому массиву, созданному &, возвращенному append.

Как было предложено @JimB в комментариях, вы можете добавить заявление для печати мощности на каждом шагу в цикле дописывания, чтобы увидеть, как это происходит:

fmt.Println(cap(data.P)) 

должны генерировать что-то вроде:

2 
2 
4 
4 
8 
8 
8 
8 
16 
16 
+0

Это правильно. благодаря! – xrfang

+0

@xrfang, добро пожаловать! –

Смежные вопросы