Boş dilimi başlatmanın doğru yolu


227

Sabit olmayan bir boyuta sahip boş bir dilim beyan etmek yapmak daha iyidir:

mySlice1 := make([]int, 0)

veya:

mySlice2 := []int{}

Hangisinin doğru yol olduğunu merak ediyorum.


2
"Sabit olmayan boyut" diyorsunuz, ancak dilimler asla sabit boyuta sahip değil. Sıfır kapasite demek istemediğiniz sürece. Hangi kapasiteye ihtiyacınız olabileceği hakkında bir fikriniz / tahmininiz / ipucunuz varsa, üç bağımsız değişken sürümünü kullanmanın iyi olduğunu unutmayın. Örneğin, bir dilim harita anahtarı oluşturmak için:keys := make([]int, 0, len(m)); for k, v := range m { keys := append(keys,k) }
Dave C

Yanıtlar:


274

Verdiğiniz iki alternatif anlamsal olarak aynıdır, ancak kullanmak runtime.makeslicemake([]int, 0) için dahili bir çağrıya neden olacaktır (Go 1.14).

Ayrıca bir nildeğerle bırakma seçeneğiniz de vardır :

var myslice []int

Golang.org blogunda yazıldığı gibi :

sıfır dilim, hiçbir şeye işaret etmese de işlevsel olarak sıfır uzunluklu bir dilim ile eşdeğerdir. Uzunluğu sıfırdır ve ayırma ile eklenebilir.

nilAncak bir dilim json.Marshal()içine girerken "null", boş bir dilim "[]"@farwayer tarafından işaret edildiği gibi içine girecek.

Yukarıdaki seçeneklerin hiçbiri @ArmanOrdookhani tarafından belirtildiği gibi herhangi bir ayırmaya neden olmaz.



106
Be bakım: json.Marshal()dönecektir nulliçin var myslice []intve []başlatılmış dilim içinmyslice := []int{}
farwayer

10
Ayrıca dikkat edin: reflect.DeepEqualnil dilimleri ve olmayan nil dilimler arasında bir ayrım yapan: a := []int{}, var b []int,reflect.DeepEqual(a, b) // returns false
asgaines

1
Neden tahsis edeceğini düşünüyorsun? Sınır sıfır olduğundan hiçbir şey tahsis edilmez. Sıfır uzunluktaki şeylere yönelik tüm işaretçiler bellekte aynı yeri gösterir: play.golang.org/p/MPOKKl_sYvw
Arman Ordookhani

1
@ArmanOrdookhani Doğru. Bunu denedim ve aynı montaj talimatları hakkındaki varsayımla yanlış olduğumu da öğrendim. Sabit!
ANisus

65

Eşdeğerler. Bu koda bakın:

mySlice1 := make([]int, 0)
mySlice2 := []int{}
fmt.Println("mySlice1", cap(mySlice1))
fmt.Println("mySlice2", cap(mySlice2))

Çıktı:

mySlice1 0
mySlice2 0

Her iki dilim de 0her iki dilimin 0uzunluğuna (kapasiteden daha büyük olamaz) sahip olduğu ve her iki dilimin de eleman içermediğini ima eden kapasiteye sahiptir. Bu, 2 dilimin her yönüyle aynı olduğu anlamına gelir.

Benzer sorulara bakın:

Golang'da sıfır dilim ve boş dilim olmanın anlamı nedir?

Go dilinde nil dilimleri vs nil olmayan dilimleri vs boş dilimleri


46

@ ANISUS'un cevabına ek olarak ...

Aşağıda, bahsetmeye değer olduğunu düşündüğüm "Harekete Geçin" kitabından bazı bilgiler verilmiştir :

nil& emptyDilimleri arasındaki fark

Böyle bir dilim düşünürsek:

[pointer] [length] [capacity]

sonra:

nil slice:   [nil][0][0]
empty slice: [addr][0][0] // points to an address

sıfır dilim

Dilim döndüren bir işlevde istisna oluştuğunda olduğu gibi, var olmayan bir dilimi temsil etmek istediğinizde kullanışlıdır.

// Create a nil slice of integers.
var slice []int

boş dilim

Boş dilimler, veritabanı sorgusunun sıfır sonuç döndürmesi gibi boş bir koleksiyonu temsil etmek istediğinizde yararlıdır.

// 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{}

Ne olursa olsun bir nil dilim veya boş dilim, yerleşik işlevleri kullanıyor olun append, lenve capaynı işi.


Oyun alanına git :

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))

}

baskılar:

true 0 0
false 0 0

Boş dilim adresini tek adımda alabilir miyiz make?
Simin Jie

Biz fonksiyon bir göz atacak olursak imza , makeadres dönmek için görünmüyor. Tek adımda yapamayacağınıza inanıyorum.
tgogos

13

Go'da boş dilim ve sıfır dilim farklı şekilde başlatılır:

var nilSlice []int 
emptySlice1 := make([]int, 0)
emptySlice2 := []int{}

fmt.Println(nilSlice == nil)    // true
fmt.Println(emptySlice1 == nil) // false
fmt.Println(emptySlice2 == nil) // false

Her üç dilime gelince, len ve kapak 0'dır.


make([]int, 0)Jetbrains GoLand'ın bu durumda olduğu gibi "gereksiz" olduğundan şikayet etmediği için en iyisidir []int{}. Bu, birim testleri yazarken yararlıdır.
Andrzej Rehmann
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.