Dizi tanımlamak
Bir dizi tipi [N]T şeklinde yazılır: bir uzunluk, sonra bir eleman tipi. Uzunluk derleme zamanında sabitlenir ve tipin bir parçasıdır.
Çıktı:
[90 0 0 0 75] 5
Tue
[5]int [2 3 5 7 11]
["" "b" "" "d" ""]
Bir dizi her zaman tamamen başlatılmıştır. Ayarlamadığınız elemanlar eleman tipinin sıfır değerini tutar: 0, "", false, nil.
İndeksleme ve sınırlar
İndeksler 0'dan len(a)-1'e kadar gider. Aralık dışındaki sabit bir indeks derleme hatasıdır. Aralık dışındaki değişken bir indeks çalışma zamanında panic'e yol açar.
var a [3]int
a[5] = 1 // compile error: invalid argument: index 5 out of bounds [0:3]
i := 5
a[i] = 1 // panic: runtime error: index out of range [5] with length 3
Dolaşmak
for i, v := range a her elemanı sırayla ziyaret eder. v elemanın bir kopyasıdır, bu yüzden v'ye atama yapmak diziyi değiştirmez. Bunun yerine indeks üzerinden yazın.
Dizilere özgü bir incelik daha var: bir dizi değeri üzerinde range, başta dizinin bir kopyasını değerlendirir. Gövde sonraki elemanları değiştirirse v hâlâ eski değerleri gösterir. &a ya da a[:] üzerinde range yapmak kopyadan kaçınır.
Diziler değerdir
C, Java ya da JavaScript'teki dizilerden asıl fark budur. Bir diziyi atamak her elemanı kopyalar. Bir diziyi bir fonksiyona aktarmak da onu kopyalar.
Çıktı:
[1 2 3] [99 2 3]
[1 2 3]
[0 2 3]
Kopyalamak küçük diziler için ucuz, büyükler için pahalıdır: bir [1_000_000]int'i değerle aktarmak sekiz megabayt kopyalar. Dizi büyükse ya da fonksiyonun onu değiştirmesi gerekiyorsa bir pointer (*[N]T) ya da bir slice (a[:]) aktarın. Bir dizi pointer'ı üzerinden indekslemek açık bir * gerektirmez: a[0] bir *[3]int üzerinde çalışır.
Dizileri karşılaştırmak ve map anahtarı olarak kullanmak
Karşılaştırılabilir elemanlardan oluşan diziler == ve != destekler. Her elemanı eşit olan iki dizi eşittir. Bu, onları slice'ların olamadığı geçerli map anahtarları da yapar.
Farklı uzunluktaki diziler farklı tiplerdir ve hiç karşılaştırılamaz: [3]int{} == [4]int{} derlenmez (mismatched types [3]int and [4]int).
Çok boyutlu diziler
Dizilerden oluşan bir dizi size sabit bir ızgara verir. Izgaranın tamamı tek bir bitişik bellek bloğudur.
row[:], [3]rune satırını string()'in kabul ettiği bir []rune slice'ına çevirir.
Diziler ve slice'lar
Dizi [N]T | Slice []T | |
|---|---|---|
| Uzunluk | sabit, tipin parçası | append ile değişir |
| Atama ve aktarım | tüm elemanları kopyalar | küçük bir başlığı kopyalar, elemanları paylaşır |
| Sıfır değer | N sıfır eleman | nil, uzunluk 0 |
== | evet, eleman eleman | yalnızca nil'e karşı |
| Map anahtarı | evet | hayır |
| Tipik kullanım | sabit boyutlu veri: hash'ler, koordinatlar, buffer'lar | geri kalan hemen her şey |
Pratikte dizilerle çoğunlukla birkaç yerde karşılaşırsınız: sha256.Sum256 bir [32]byte döndürür, boyutu hiç değişmeyen arama tabloları ve bir slice'ın arka deposu olarak. Bir diziyi a[:] ya da a[1:3] ile dilimlemek belleğini paylaşan bir slice oluşturur; bu paylaşımın ne anlama geldiğini slices sayfası anlatıyor.
Diziler ile slice'lar arasında dönüşüm
Bir slice'ı bir diziye (Go 1.20) ya da bir dizi pointer'ına (Go 1.17) dönüştürmek, slice dizi uzunluğundan kısaysa panic'e yol açar: panic: runtime error: cannot convert slice with length 2 to array or pointer to array with length 3.
Sık yapılan hatalar
- Bir fonksiyonun dizi argümanını değiştirmesini beklemek. Fonksiyon bir kopya alır.
*[N]Tya da bir slice aktarın. - Slice istenen yerde dizi kullanmak.
[]int{1, 2}bir slice,[2]int{1, 2}bir dizidir.[]intalan bir fonksiyon bir[2]intkabul etmez;a[:]aktarın. - range döngüsünde büyük diziler.
for _, v := range bigArrayönce dizinin tamamını kopyalar.&bigArrayya da bir slice üzerinde range yapın.
Sıkça Sorulan Sorular
Go'da dizi nasıl tanımlanır?
Uzunluğu eleman tipinden önce köşeli parantez içinde yazın: var a [5]int beş sıfır oluşturur. Değerlerle: a := [3]string{"x", "y", "z"}. Derleyicinin saymasını istiyorsanız [...] kullanın: a := [...]int{1, 2, 3} ifadesinin tipi [3]int'tir.
Go'da dizi ile slice arasındaki fark nedir?
Bir dizinin uzunluğu sabittir ve tipinin bir parçasıdır ([3]int ile [4]int farklı tiplerdir); atandığında ya da aktarıldığında kopyalanır. Bir slice ([]int) ise alttaki bir diziye açılan, uzunluğu append ile değişebilen bir görünümdür ve bir slice'ı kopyalamak elemanları değil yalnızca görünümü kopyalar. Go kodunun çoğu slice kullanır.
Go'da bir dizinin uzunluğu nasıl alınır?
Yerleşik len(a) fonksiyonunu kullanın. Bir dizi için bu derleme zamanı sabitidir, bu yüzden sabit ifadelerde kullanabilirsiniz. cap(a) aynı sayıyı döndürür.
Go'da diziler karşılaştırılabilir mi?
Evet, eleman tipi karşılaştırılabilirse == ve != ile. Tüm elemanları eşit olan iki dizi eşittir. Diziler map anahtarı da olabilir. Slice'lar == ile karşılaştırılamaz (nil hariç); onlar için slices.Equal kullanın.