среда, 15 апреля 2020 г.

Как лучше всего очистить срез в Golang: пустой против нулевого

Удалить все элементы

Чтобы удалить все элементы, просто установите срез равным nil.

a := []string{"A", "B", "C", "D", "E"}
a = nil
fmt.Println(a, len(a), cap(a)) // [] 0 0

Это освободит подлежащий массив для сборщика мусора (при условии, что нет других ссылок).

Сохранить выделенную память

Чтобы сохранить подлежащий массив, нарежьте срез до нулевой длины.

a := []string{"A", "B", "C", "D", "E"}
a = a[:0]
fmt.Println(a, len(a), cap(a)) // [] 0 5

Если срез снова расширяется, исходные данные появляются снова.

fmt.Println(a[:2]) // [A B]

Пустой срез против нулевого среза

На практике нулевые срезы и пустые срезы часто можно обрабатывать одинаково:

  • они имеют нулевую длину и емкость,
  • они могут использоваться с одинаковым эффектом в циклах и функциях append,
  • и они даже выглядят одинаково при печати.

var a []int = nil
fmt.Println(len(a)) // 0
fmt.Println(cap(a)) // 0
fmt.Println(a)      // []

b := []int{}
fmt.Println(len(b)) // 0
fmt.Println(cap(b)) // 0
fmt.Println(b)      // []

Однако при необходимости вы можете заметить разницу.

var a []int = nil
var a0 []int = make([]int, 0)

fmt.Println(a == nil)  // true
fmt.Println(a0 == nil) // false

fmt.Printf("%#v\n", a)  // []int(nil)
fmt.Printf("%#v\n", a0) // []int{}

Официальная Go wiki рекомендует использовать нулевые срезы вместо пустых срезов.

Нулевой срез является предпочтительным стилем.

Обратите внимание, что существуют ограниченные обстоятельства, когда предпочтителен не nil срез, а срез нулевой длины, например, при кодировании объектов JSON (nil срез кодируется в null, а []string{} кодируется в массив JSON []).

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


Читайте также:


Комментариев нет:

Отправить комментарий