Sabit bir dizi bildirin


164

Denedim:

const ascii = "abcdefghijklmnopqrstuvwxyz"
const letter_goodness []float32  = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
const letter_goodness  = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
const letter_goodness = []float32 { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }

Birincisi, deklarasyon ve başlatma iyi çalışıyor, ancak ikinci, üçüncü ve dördüncü işe yaramıyor. Sabit şamandıra dizisini nasıl bildirebilir ve başlatabilirim?

Yanıtlar:


232

Bir dizi doğası gereği değişmez değildir; sabit yapamazsın.

Alabileceğiniz en yakın şey:

var letter_goodness = [...]float32 {.0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007 }

[...]Bunun yerine not alın []: bir dilim yerine (sabit boyutlu) bir dizi almanızı sağlar. Bu yüzden değerler sabit değildir, ancak boyut sabittir.


126
Sadece açıklığa kavuşturmak için: [...]Tsözdizimi şekerdir [123]T. Sabit boyutlu bir dizi oluşturur, ancak derleyicinin içinde kaç öğe olduğunu bulmasına izin verir.
jimt

5
Sabit dizilere izin vermenin tip sistemde güncellemeler gerektireceğini tahmin ediyorum. Aksi takdirde, bir işlev tanımladıysanız f(xs [5]int), iletilen dizinin sabit mi yoksa değişken mi olduğunu bilemezsiniz.
Thomas Ahle

tks, dizeleri denediğimde sorun yaşıyorum.Join cannot use constants.FilesRequired (type [4]string) as type []string in argument to strings.Join
Eddy Hernandez

Dilim çözümü için teşekkürler. Şüphe: Bir dizinin kendisi değişmez, değil mi? Dizi oluşturulduktan sonra eleman eklenemez veya kaldırılamaz, değil mi? Ancak dizi öğelerini düzenleyebilirim.
legends2k

@ legends2k Dizinin boyutunu değiştiremezsiniz, evet, ancak yuvalarına başka değerler de ekleyebilirsiniz.
Denys Séguret

63

Gönderen Etkili Go :

Go'daki sabitler tam da bu - sabittir. Bunlar, işlevlerde yerel olarak tanımlansalar bile derleme zamanında oluşturulur ve yalnızca sayı, dize veya boolean olabilir. Derleme zamanı kısıtlaması nedeniyle, bunları tanımlayan ifadelerin derleyici tarafından değerlendirilebilen sabit ifadeler olması gerekir. Örneğin, 1 << 3 sabit bir ifadedir, math.Sin (math.Pi / 4) işlevi, math.Sin işlev çağrısının çalışma zamanında gerçekleşmesi gerektiği için değildir.

Dilimler ve diziler çalışma zamanında her zaman değerlendirilir:

var TestSlice = []float32 {.03, .02}
var TestArray = [2]float32 {.03, .02}
var TestArray2 = [...]float32 {.03, .02}

[...]derleyiciye dizinin kendisinin uzunluğunu bulmasını söyler. Dilimler dizileri sarar ve çoğu durumda çalışmak daha kolaydır. Sabitleri kullanmak yerine, küçük harfli ilk harfi kullanarak değişkenleri diğer paketler için erişilemez hale getirin:

var ThisIsPublic = [2]float32 {.03, .02}
var thisIsPrivate = [2]float32 {.03, .02}

thisIsPrivateyalnızca tanımlandığı pakette kullanılabilir. Dışarıdan okuma erişimine ihtiyacınız varsa, basit bir alıcı işlevi yazabilirsiniz (bkz . Golang'daki Harfler ).


12

Go'da dizi sabiti diye bir şey yoktur.

Git Dili Şartnamesinden Alıntı : Sabitler :

Orada boolean sabitleri , rün sabitleri , tamsayı sabitler , kayan nokta sabitleri , kompleks sabitler ve dize sabitleri . Rune, integer, kayan nokta ve karmaşık sabitlere topluca sayısal sabitler denir .

Bir Sabit ifade (bir sabiti başlatmak için kullanılır) yalnızca sabit işlenenler içerebilir ve derleme zamanında değerlendirilir.

Spesifikasyon, farklı sabit türlerini listeler. Temel tür olarak izin verilen türlerden birine sahip türlerin sabit ifadeleriyle sabitler oluşturabileceğinizi ve başlatabileceğinizi unutmayın . Örneğin bu geçerlidir:

func main() {
    type Myint int
    const i1 Myint = 1
    const i2 = Myint(2)
    fmt.Printf("%T %v\n", i1, i1)
    fmt.Printf("%T %v\n", i2, i2)
}

Çıktı ( Go Playground'da deneyin ):

main.Myint 1
main.Myint 2

Bir diziye ihtiyacınız varsa, bu sadece bir değişken olabilir, ancak sabit olamaz.

Sabitler hakkında bu harika blog makalesini öneriyorum: Sabitler


sabit boyutlu bir kaba ihtiyaç duyarsanız ne yapmalı?

@Atomic_alarm Lütfen biraz açıklayabilir misiniz?
icza

Golang analog C-dizisinde olup olmadığı var mı?

@Atomic_alarm Evet, Go'da diziler de var, bunlar sadece sabit ifadeler değil, çalışma zamanında değerlendiriliyor. Dolayısıyla, sabit bir dizi türünde olamaz, ancak bir değişken olabilir. Örneğin:var arr = [2]int{2, 3}
icza

3

Diğerlerinin de belirttiği gibi, bunun için resmi bir Go yapısı yoktur. Hayal edebileceğim en yakın şey bir dilim döndüren bir işlev olurdu. Bu şekilde, kimsenin orijinal dilimin elemanlarını manipüle etmeyeceğini garanti edebilirsiniz (diziye "sabit kodlanmış" olduğundan).

Diliminizi kısaltmak için kısalttım ... daha kısa ...:

func GetLetterGoodness() []float32 {
    return [...]float32 { .0817,.0149,.0278,.0425,.1270,.0223 }
}

4
bu en iyi yol gibi görünüyor, ancak işlev dönüş türü eşleşmiyor. cannot use [6]string literal (type [6]string) as type []string in return argumentyanireturn []float32 { ... }
17'de theRemix

@theRemix Üç olası düzeltme: (1) ...bir dizi değişmez değeri yerine bir dilim değişmezi bildirmek için kaldırın . (2) dönüş türünü değiştirin [6]float32. (3) bir dizi değişkene ifade atayabilir a := [...]float32 { (etc.) }ve tüm elemanların dilim dönüş: return a[:]. (Dizi değişmezleri adreslenebilir değil, nedenini açık değilim.)
David Moles

Seni ne garanti ettiğini bilmiyorum. Kodunuzda (birim-) testlerle muhtemelen daha iyi çözülmüş bir şeyi çözmeye çalıştığınız anlaşılıyor.
Dynom
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.