Go Dil Spesifikasyonu ( Adres operatörleri ) bir sayısal sabitin ( türlenmemiş veya yazılan sabitin değil) adresini almaya izin vermez .
İşlenen adreslenebilir , yani bir değişken, işaretçi indirimi veya dilim indeksleme işlemi olmalıdır; veya adreslenebilir yapı işleneni alan seçicisi; veya adreslenebilir bir dizinin dizi indeksleme işlemi. Adreslenebilirlik gereksinimine bir istisna olarak, x
[ifadesindeki &x
] bir (muhtemelen parantez içinde) birleşik sabit bilgi de olabilir .
Neden buna izin verilmediğini anlamak için ilgili soruya bakın: Hareket halindeyken sabitin adresini bulun . Benzer bir soru (benzer şekilde adresini almasına izin verilmez): Go'da bir işlemin sonucuna ilişkin referansı nasıl saklayabilirim?
Seçenekleriniz (hepsini Go Oyun Alanında deneyin ):
1) İle new()
new()
Yeni bir sıfır değerli tahsis etmek int64
ve adresini almak için yerleşik işlevini kullanabilirsiniz :
instance := SomeType{
SomeField: new(int64),
}
Ancak bunun yalnızca herhangi bir türün sıfır değerine bir gösterici tahsis etmek ve elde etmek için kullanılabileceğini unutmayın.
2) Yardımcı değişken ile
Sıfır olmayan öğeler için en basit ve önerilen, adresi alınabilen bir yardımcı değişken kullanmaktır:
helper := int64(2)
instance2 := SomeType{
SomeField: &helper,
}
3) Yardımcı işlevi ile
Not: Sıfırdan farklı bir değere işaretçi edinmeye yönelik yardımcı işlevler, github.com/icza/gox
kitaplığımda, gox
pakette mevcuttur, bu nedenle bunları ihtiyacınız olan tüm projelerinize eklemeniz gerekmez.
Veya buna birçok kez ihtiyacınız varsa, aşağıdakileri ayıran ve döndüren bir yardımcı işlev oluşturabilirsiniz *int64
:
func create(x int64) *int64 {
return &x
}
Ve bunu kullanarak:
instance3 := SomeType{
SomeField: create(3),
}
Aslında hiçbir şey ayırmadığımıza dikkat edin, Go derleyicisi bunu işlev bağımsız değişkeninin adresini döndürdüğümüzde yaptı. Go derleyicisi, kaçış analizi gerçekleştirir ve işlevden çıkabilirlerse, yığın üzerinde yerel değişkenleri (yığın yerine) tahsis eder. Ayrıntılar için bkz. Go işlevinde yerel dizinin bir dilimini döndürmek güvenli midir?
4) Tek satırlık anonim işlev ile
instance4 := SomeType{
SomeField: func() *int64 { i := int64(4); return &i }(),
}
Veya (daha kısa) bir alternatif olarak:
instance4 := SomeType{
SomeField: func(i int64) *int64 { return &i }(4),
}
5) Dilim değişmezi, indeksleme ve adres alma ile
İstediğiniz istiyorsanız *SomeField
dışında olması 0
, o zaman bir şey adreslenebilir gerekir.
Hala yapabilirsin, ama bu çirkin:
instance5 := SomeType{
SomeField: &[]int64{5}[0],
}
fmt.Println(*instance2.SomeField)
Burada olan şey []int64
, bir öğeye ( 5
) sahip olan bir dilimin değişmez değerle yaratılmasıdır . Ve indekslenir (0. element) ve 0. elementin adresi alınır. Arka planda bir dizi [1]int64
de tahsis edilecek ve dilim için destek dizisi olarak kullanılacaktır. Yani burada pek çok standart metin var.
6) Bir yardımcı yapı hazır bilgisi ile
Adreslenebilirlik gereksinimlerindeki istisnayı inceleyelim:
Adreslenebilirlik gereksinimine bir istisna olarak, x
[ifadesindeki &x
] bir (muhtemelen parantez içinde) birleşik sabit bilgi de olabilir .
Bu, birleşik bir değişmezin adresini almanın, örneğin bir struct literal'in uygun olduğu anlamına gelir. Bunu yaparsak, tahsis edilen struct değerine ve ona elde edilen bir göstericiye sahip oluruz. Fakat eğer öyleyse, başka bir gereksinim bizim için geçerli olacaktır: "adreslenebilir yapı işleneni alan seçicisi" . Yani yapı değişmezi bir tür alanı içeriyorsa int64
, o alanın adresini de alabiliriz!
Bu seçeneği iş başında görelim. Bu sarmalayıcı yapı türünü kullanacağız:
type intwrapper struct {
x int64
}
Ve şimdi yapabiliriz:
instance6 := SomeType{
SomeField: &(&intwrapper{6}).x,
}
Bunu unutmayın
&(&intwrapper{6}).x
şu anlama gelir:
& ( (&intwrapper{6}).x )
Ancak, adres operatörü seçici ifadenin&
sonucuna uygulandığı için "dış" parantezi atlayabiliriz .
Ayrıca arka planda aşağıdakilerin olacağını unutmayın (bu aynı zamanda geçerli bir sözdizimidir):
&(*(&intwrapper{6})).x
7) Yardımcı anonim yapı hazır bilgisi ile
İlke 6 numaralı durumla aynıdır, ancak anonim bir yapı değişmezi de kullanabiliriz, bu nedenle yardımcı / sarmalayıcı yapı türü tanımına gerek yoktur:
instance7 := SomeType{
SomeField: &(&struct{ x int64 }{7}).x,
}