Скорее всего, вы уже сталкивались с panic: runtime error: makeslice: cap out of range
. Эта ошибка, как правило, возникает при работе со слайсами, и сегодня мы разберемся, почему она появляется и как ее избежать.

Суть проблемы: длина и емкость слайса
В Go слайс — это динамический массив, который ссылается на часть базового массива. У слайса есть два ключевых параметра:
- Длина (length): Количество элементов, которые слайс содержит.
- Емкость (capacity): Количество элементов, которые могут быть размещены в базовом массиве без перераспределения памяти.
И вот тут кроется главная причина ошибки: длина слайса всегда должна быть меньше или равна его емкости. Ссылка на оф. документацию
Почему возникает panic: runtime error: makeslice: cap out of range
?
Эта ошибка возникает, когда вы пытаетесь создать слайс, у которого емкость меньше, чем длина. Проще говоря, вы говорите Go: «Я хочу слайс, который содержит 10 элементов, но у него есть место только для 5». Go, естественно, не может этого сделать и вызывает панику.
Пример, который вызывает ошибку:
Go
package main
import "fmt"
func main() {
// Пытаемся создать слайс с длиной 10 и емкостью 5.
k := make([]int, 10, 5)
fmt.Println(k)
}
При запуске этого кода вы увидите:
panic: runtime error: makeslice: cap out of range
Почему это не ошибка компиляции?
Вы могли бы подумать: «Почему компилятор не обнаруживает эту ошибку?» Дело в том, что значения длины и емкости слайса могут быть определены во время выполнения программы.
Пример, когда значения определяются во время выполнения:
Go
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
length := rand.Intn(10) // Случайная длина
capacity := rand.Intn(5) // Случайная емкость
// Ошибка может возникнуть, если length > capacity.
k := make([]int, length, capacity)
fmt.Println(k)
}
В этом примере значения length
и capacity
определяются случайным образом во время выполнения. Компилятор не может предсказать, будут ли они корректными.
Как избежать ошибки?
- Всегда проверяйте, что длина меньше или равна емкости. Если вы получаете значения длины и емкости из внешних источников, убедитесь, что они соответствуют этому правилу.
- Используйте
append
для добавления элементов. Если вы не знаете заранее, сколько элементов будет в слайсе, используйте функциюappend
. Она автоматически увеличивает емкость слайса, если это необходимо. - Если вы знаете только длину, не указывайте емкость. Если вы знаете только длину слайса, не указывайте емкость. Go автоматически установит емкость равной длине.
Пример правильного использования append
:
package main
import "fmt"
func main() {
k := make([]int, 0, 5) // Создаем слайс с длиной 0 и емкостью 5.
for i := 0; i < 10; i++ {
k = append(k, i) // Добавляем элементы.
}
fmt.Println(k)
}
В этом примере мы создаем слайс с длиной 0 и емкостью 5. Затем мы добавляем 10 элементов с помощью append
. Go автоматически увеличивает емкость слайса, когда это необходимо.
Вывод
panic: runtime error: makeslice: cap out of range
— это распространенная ошибка, которая возникает, когда вы пытаетесь создать слайс с емкостью, меньшей, чем его длина. Всегда помните, что 0 <= len(s) <= cap(s)
. Используйте append
для динамического добавления элементов и проверяйте значения длины и емкости, если они определяются во время выполнения.
Надеюсь, эта статья помогла вам разобраться с этой ошибкой.
Оставить комментарий