Для оголошення порожнього фрагмента з нефіксованим розміром краще зробити:
mySlice1 := make([]int, 0)
або:
mySlice2 := []int{}
Просто цікаво, який з них є правильним.
Для оголошення порожнього фрагмента з нефіксованим розміром краще зробити:
mySlice1 := make([]int, 0)
або:
mySlice2 := []int{}
Просто цікаво, який з них є правильним.
Відповіді:
Дві альтернативи, які ви подали, є семантично однаковими, але їх використання make([]int, 0)
призведе до внутрішнього виклику runtime.makeslice (Перейти 1.14).
Ви також можете залишити його зі nil
значенням:
var myslice []int
Як написано в блозі Golang.org :
нульовий зріз функціонально еквівалентний зрізу нульової довжини, хоча він не вказує ні на що. Він має нульову довжину і до нього можна додавати виділення.
Однак nil
шматочок потрапить json.Marshal()
у "null"
той час, коли порожній шматочок буде маршалити"[]"
, як вказував @farwayer.
Жоден з перерахованих вище варіантів не призведе до виділення, як вказував @ArmanOrdookhani.
json.Marshal()
повернуться null
до var myslice []int
і []
для ініціалізувала зрізуmyslice := []int{}
reflect.DeepEqual
розрізняє нульовими часточки і не-нульовими скибочок: a := []int{}
, var b []int
,reflect.DeepEqual(a, b) // returns false
Вони рівноцінні. Дивіться цей код:
mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))
Вихід:
mySlice1 0
mySlice2 0
Обидва скибочки мають 0
ємність, що означає, що обидва скибочки є0
довжину (не може бути більшою, ніж ємність), що означає, що обидва скибочки не мають елементів. Це означає, що 2 скибочки в кожному аспекті однакові.
Дивіться подібні запитання:
Який сенс мати нульовий шматочок та порожній шматочок у голангу?
nil slices vs non-nil фрагменти vs порожні фрагменти на мові Go
Як додаток до відповіді @ANisus ...
нижче наводиться деяка інформація з книги "Іди в дії" , яку, на мою думку, варто згадати:
nil
& empty
скибочкамиЯкщо ми думаємо про такий фрагмент:
[pointer] [length] [capacity]
тоді:
nil slice: [nil][0][0]
empty slice: [addr][0][0] // points to an address
нульовий шматочок
Вони корисні, коли ви хочете представити фрагмент, який не існує, наприклад, коли у функції, яка повертає фрагмент, відбувається виняток.
// Create a nil slice of integers. var slice []int
порожній шматочок
Порожні фрагменти корисні, коли ви хочете представляти порожню колекцію, наприклад, коли запит бази даних повертає нульові результати.
// Use make to create an empty slice of integers. slice := make([]int, 0) // Use a slice literal to create an empty slice of integers. slice := []int{}
Незалежно від того, чи використовуєте ви нульовий скибочку або порожній шматок, вбудовані в функції
append
,len
іcap
працювати так само.
Перейдіть на приклад ігрового майданчика :
package main
import (
"fmt"
)
func main() {
var nil_slice []int
var empty_slice = []int{}
fmt.Println(nil_slice == nil, len(nil_slice), cap(nil_slice))
fmt.Println(empty_slice == nil, len(empty_slice), cap(empty_slice))
}
відбитки:
true 0 0
false 0 0
make
?
Порожній зріз і нульовий фрагмент ініціалізуються по-різному:
var nilSlice []int
emptySlice1 := make([]int, 0)
emptySlice2 := []int{}
fmt.Println(nilSlice == nil) // true
fmt.Println(emptySlice1 == nil) // false
fmt.Println(emptySlice2 == nil) // false
Що стосується всіх трьох скибочок, то лен і кришка - 0.
make([]int, 0)
найкраще, тому що Jetbrains GoLand не скаржиться на те, що він "непотрібний", як це робиться у випадку []int{}
. Це корисно при написанні одиничних тестів.
keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }