Menu

Golang Dizi (Array): Sabit Uzunluk, Değer Semantiği, Slice Farkı

Bir Go dizisinin uzunluğu sabittir ve tipinin bir parçasıdır; atamada kopyalanır. Dizileri tanımlamayı, dolaşmayı, karşılaştırmayı ve aktarmayı, ve Go kodunun çoğunun neden bunun yerine slice kullandığını öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

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]TSlice []T
Uzunluksabit, tipin parçasıappend ile değişir
Atama ve aktarımtüm elemanları kopyalarküçük bir başlığı kopyalar, elemanları paylaşır
Sıfır değerN sıfır elemannil, uzunluk 0
==evet, eleman elemanyalnızca nil'e karşı
Map anahtarıevethayır
Tipik kullanımsabit boyutlu veri: hash'ler, koordinatlar, buffer'largeri 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]T ya da bir slice aktarın.
  • Slice istenen yerde dizi kullanmak. []int{1, 2} bir slice, [2]int{1, 2} bir dizidir. []int alan bir fonksiyon bir [2]int kabul etmez; a[:] aktarın.
  • range döngüsünde büyük diziler. for _, v := range bigArray önce dizinin tamamını kopyalar. &bigArray ya 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.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA