Menu

Golang const: Tipli ve Tipsiz Sabitler

Go'da const nasıl çalışır: sabit tanımlamak, tipli ve tipsiz sabitler arasındaki fark, keyfi hassasiyetli sabit ifadeler ve Go'da neden sabit slice, map ya da struct olmadığı.

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

Sabit, derleme zamanında belirlenen bir değerdir. const ile tanımlayın; Go onu değiştirme girişimlerinin hepsini reddeder.

Sabitler paket seviyesinde ya da bir fonksiyonun içinde, her satıra bir tane ya da bir const ( ... ) bloğunda gruplanarak tanımlanabilir. MB ve GB başka sabitlerden hesaplanır ve derleyici bu aritmetiği bir kez, derleme sırasında yapar.

MaxRetries = 5 gibi bir sabite atama yapmak derleme hatasıdır:

./main.go:8:2: cannot assign to MaxRetries (neither addressable nor a map index expression)

Neler Sabit Olabilir

Yalnızca üç tür değer: boolean'lar, sayılar (tam sayılar, ondalıklı sayılar, karmaşık sayılar ve rune'lar) ve string'ler. Değerin derleyici tarafından hesaplanabilir olması gerekir; bu da literal'ler, diğer sabitler, bunlar üzerindeki aritmetik ve sabit bir string'in len'i gibi birkaç yerleşik fonksiyon demektir.

Kod çalıştırmayı ya da bellek ayırmayı gerektiren her şey dışarıda kalır:

const Colors = []string{"red", "green"} // slice
const Started = time.Now()              // function call
./main.go:9:16: []string{…} (value of type []string) is not constant
./main.go:10:13: time.Now() (value of struct type time.Time) is not constant

Go'da Neden Sabit Slice ya da Map Yok

Slice'lar, map'ler ve bunları içeren struct'lar çalışma zamanında var olan belleğe referanslardır, bu yüzden derleyici onları programa sabit değerler olarak gömemez; Go'da değişkenler için readonly ya da final niteleyicisi de yoktur. Yaygın geçici çözümler:

Kopya her çağrıda bir bellek ayırmaya mal olur; bu, yapılandırma boyutundaki veriler için sorun değildir. Anahtarla arama için bir fonksiyonun içindeki switch sabite benzer başka bir seçenektir: func statusText(code int) string { switch code { ... } }.

Tipsiz Sabitler

Tip belirtilmeden tanımlanan bir sabit tipsizdir. Bir türü (tam sayı, ondalıklı, rune, string, bool) vardır ama kullanılana kadar belirli bir Go tipi yoktur ve bağlama uyum sağlar:

Ratio, dönüşüm olmadan bir int, bir float64, bir uint8 ve bir float32 olarak çalışır. time.Sleep(2 * time.Second) ifadesinin derlenmesinin nedeni budur: 2 tipsizdir ve bir time.Duration olur.

Bağlam bir tip istemediğinde, x := Ratio örneğinde olduğu gibi, sabit kendi varsayılan tipini alır:

Tipsiz sabit türüVarsayılan tip
tam sayı (42)int
ondalıklı (4.2)float64
rune ('a')rune (int32)
karmaşık (2i)complex128
stringstring
booleanbool

Kesin aritmetik

Tipsiz sayısal sabitler kesindir. Derleyici tam sayıları en az 256 bitle temsil eder, bu yüzden ara değerler herhangi bir Go tipinden çok daha büyük olabilir:

Huge'ın kendisi bir tam sayı olarak yazdırılamaz, çünkü onu fmt.Println'e vermek int'e dönüştürür ve derleyici bunu yakalar (float64(Huge) çalışır, çünkü bir float bu büyüklüğü tutabilir):

cannot use Huge (untyped int constant 1267650600228229401496703205376) as int value in argument to fmt.Println (overflows)

Aynı kontrol daha küçük hataları da derleme zamanında durdurur, örneğin var b byte = 300:

cannot use 300 (untyped int constant) as byte value in variable declaration (overflows)

Tipli Sabitler

Bir sabite tip verdiğinizde, Go'nun tipleri karıştırmayı reddetmesi dahil her yerde o tipin bir değeri gibi davranır:

const Limit int = 10

var f float64 = 2
fmt.Println(Limit * f)
invalid operation: Limit * f (mismatched types int and float64)

const Limit = 10 (tipsiz) ile Limit * f derlenir ve 20 verir. Bu yüzden tip bir anlam taşımadıkça sabitleri tipsiz bırakın. Kendi adlandırılmış tipinizde sabitler tanımladığınızda tip anlam taşır; Go enum'ları böyle kurar:

type Weekday int

const (
	Sunday Weekday = iota
	Monday
	Tuesday
)

Burada asıl mesele tiptir: Weekday alan bir fonksiyon ne istediğini belgeler. iota ve onun üzerine kurulan enum kalıpları enum'lar ve iota sayfasında anlatılıyor.

const ve var

constvar
Değişebilir mihayırevet
Değer ne zaman bilinirderleme zamanındaçalışma zamanında
İzin verilen tiplerbool, sayısal, stringhepsi
Çalışma zamanında bellek kullanır mıhayırevet
Adresi alınabilir mi (&x)hayırevet
Kullanılmayanı hata mıhayırevet, yerel olanlar için

Gerçekten sabit olan her şey için const kullanın: limitler, boyutlar, adlar, protokol kodları, format string'leri. Derleme zamanı taşma kontrollerini ve kesin aritmetiği bedavaya alırsınız.

Tuzaklar

Tipli sabitler uyum sağlamaz. const Timeout int = 5, dönüşüm yapılmadan time.Duration beklenen bir yere verilemez; tipsiz bir const Timeout = 5 ise çarpılabilir: Timeout * time.Second.

Tam sayı sabitlerinde tam sayı bölmesi yapılır. const Half = 1 / 2 değeri 0'dır, çünkü iki işlenen de tipsiz tam sayıdır. 0.5 elde etmek için 1.0 / 2 yazın.

Adres yok. &MaxRetries derlenmez. Bir API *int istiyorsa önce sabiti bir değişkene kopyalayın.

Sıkça Sorulan Sorular

Go'da sabit nasıl tanımlanır?

const ile: const MaxRetries = 3 ya da açık bir tiple const Timeout time.Duration = 5 * time.Second. Birkaç tanesini bir blokta gruplayın: const ( A = 1; B = 2 ). Değerin derleme zamanında hesaplanabilir olması gerekir.

Go'da const bir slice, map ya da dizi yapabilir miyim?

Hayır. Sabitler yalnızca boolean, sayı (rune'lar dahil) ve string olabilir. const Colors = []string{"red"} ifadesi is not constant hatasıyla başarısız olur. Paket seviyesinde bir var kullanın; çağıranların onu değiştirmemesi gerekiyorsa her seferinde yeni bir kopya döndüren bir fonksiyon sunun.

Go'da tipsiz sabit nedir?

const Pi = 3.14159 gibi, tip belirtilmeden tanımlanan bir sabittir. Kullanılana kadar sabit bir tipi yoktur, bu yüzden aynı sabit bir float32, bir float64 ya da değeri izin veriyorsa bir int olarak çalışır. Tipsiz sabitler aynı zamanda kesindir: derleyici en az 256 bitlik hassasiyet tutar, bu yüzden const Big = 1 << 100, yalnızca sonucu sığan ifadelerde kullandığınız sürece geçerlidir.

Go'da const ile var arasındaki fark nedir?

Bir const derleme zamanında sabitlenir ve asla değişmez; çalışma zamanında bellek kullanmaz ve yalnızca bool, sayı ya da string tutabilir. Bir var ise yeniden atanabilen bir bellek konumudur ve time.Now() gibi çalışma zamanında hesaplanan değerler dahil her tipi tutabilir.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA