Полезность полной записи среза a [low: high: max]? - PullRequest
1 голос
/ 10 января 2020

Используя запись полного среза b = a[low:high:max], можно получить срез с меньшей емкостью, чем назначенный срез a. Емкость среза b будет max - low, а хранилище элементов будет совместно использоваться с a (копия не создается). max - low должно быть меньше или равно cap(a), в противном случае мы получаем пани c:

a := make([]byte, 8)
b := a[:3:10]

panic: runtime error: slice bounds out of range [::10] with capacity 8

Какая польза от возможности получить ломтик с меньшей емкостью?

Единственное полезное приложение, которое я нашел, - это принудительное создание копии среза с append, который обходит емкость среза с уменьшенной емкостью.

    a := []int{1, 2, 3, 4, 5}
    b := a[1:3:3]
    fmt.Println("a:", a, "b:",b, "cap(b):", cap(b)) // -> a: [1 2 3 4 5] b: [2 3] cap(b): 2
    b[0] = 6
    fmt.Println("a:", a, "b:",b, "cap(b):", cap(b)) // -> a: [1 6 3 4 5] b: [6 3] cap(b): 2
    b = append(b, 7) // copy slice elements and extends capacity of b
    fmt.Println("a:", a, "b:",b, "cap(b):", cap(b)) // -> a: [1 6 3 4 5] b: [6 3 7] cap(b): 4
    b[1] = 8
    fmt.Println("a:", a, "b:",b, "cap(b):", cap(b)) // -> a: [1 6 3 4 5] b: [6 8 7] cap(b): 4

Обратите внимание, что такая копия не очевидна и требует комментария, чтобы сделать ее видимой для читателя.

Другое полезное приложение?

1 Ответ

4 голосов
/ 10 января 2020

Вызывает копирование при добавлении, но то, что он делает, немного более общее, чем это. Если вы используете его, вы можете передать фрагмент некоторому неизвестному фрагменту кода, зная, что этот код не сможет использовать этот фрагмент для чтения или записи большего количества базового массива, чем вы хотели.

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

Это не мера безопасности . Другой код в вашей программе может определенно понять, как читать или писать после конца фрагмента, используя unsafe, так или иначе. Это просто способ предотвратить неожиданные побочные эффекты. Если вы вызываете функцию со срезом в середине некоторых данных, которые вас интересуют, и эта функция может append расширять или иным образом расширять срез, разумным является использование полного выражения среза для ограничения емкости. .

...