Відповіді:
У доповненні до fabriziom «s відповіді , ви можете побачити більше прикладів на" Go скибочками: використання і внутрішні органи ", де використання для []intзгадуються:
Оскільки нульове значення фрагмента (
nil) діє як зріз нульової довжини , ви можете оголосити змінну фрагмента, а потім додати його до циклу:
// Filter returns a new slice holding only
// the elements of s that satisfy f()
func Filter(s []int, fn func(int) bool) []int {
var p []int // == nil
for _, v := range s {
if fn(v) {
p = append(p, v)
}
}
return p
}
Це означає, що для додавання фрагмента вам не потрібно виділяти пам'ять спочатку: nilфрагмента p int[]достатньо, як фрагмент для додавання.
var p []intпростішою, ніж використовувати make(яку я більше асоціюю з виділенням, хоча з обмеженням 0, воно нічого не виділяє). Що стосується читабельності, я вважаю за краще не використовувати makeтут.
p := []int{}). Оскільки ми зазвичай використовуємо :=синтаксис для декларування більшості змінних, більш природним є його скрізь, а не для виключень. Окрім цього, намагаючись продумати виділення, зазвичай підштовхують людей до передчасних оптимізацій.
Просте оголошення
var s []int
не виділяє пам'ять і sвказує на nilчас
s := make([]int, 0)
виділяє пам'ять і sвказує на пам'ять на фрагмент з 0 елементами.
Зазвичай перший є ідіоматичним, якщо ви не знаєте точного розміру вашої справи використання.
makeкарти, тому що навіть порожній mapпотребує місця, виділеного для якоїсь бухгалтерії.
nilу випадку, якщо у вашому фрагменті немає елемента, а не порожній масив. Однак, якщо makeвикористовується для створення фрагмента, замість нього повернеться порожній масив, що, як правило, є бажаним ефектом.
var s []int) призведе до отримання null, тоді як марширування порожнього зрізу ( s := make([]int, 0)) призведе до очікуваного[]
Просто знайшов різницю. Якщо ви використовуєте
var list []MyObjects
а потім ви кодуєте вихід як JSON, ви отримуєте null.
list := make([]MyObjects, 0)
результати, []як очікувалося.
Трохи повніше (ще один аргумент у make) прикладі:
slice := make([]int, 2, 5)
fmt.Printf("length: %d - capacity %d - content: %d", len(slice), cap(slice), slice)
Вийшов:
length: 2 - capacity 5 - content: [0 0]
Або з динамічним типом slice:
slice := make([]interface{}, 2, 5)
fmt.Printf("length: %d - capacity %d - content: %d", len(slice), cap(slice), slice)
Вийшов:
length: 2 - capacity 5 - content: [<nil> <nil>]
nilфрагмент, тоді як другий створюєemptyфрагмент (це термінологія, що використовується в книзі "Перехід до дії" ). Для того, щоб уникнути розміщення і той же відповідь тут, ви можете перевірити stackoverflow.com/a/45997533/1561148