Deklarasikan array konstan

164

Saya telah mencoba:

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 }

Pertama, deklarasi dan inisialisasi berfungsi dengan baik, tetapi yang kedua, ketiga dan keempat tidak berfungsi. Bagaimana saya bisa mendeklarasikan dan menginisialisasi array array floats?

demo
sumber

Jawaban:

232

Array tidak berubah secara alami; Anda tidak dapat membuatnya konstan.

Yang terdekat yang bisa Anda dapatkan adalah:

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 }

Perhatikan [...]bukan []: itu memastikan Anda mendapatkan array (ukuran tetap) bukannya sepotong. Jadi nilainya tidak tetap tetapi ukurannya.

Denys Séguret
sumber
126
Hanya untuk klarifikasi: [...]Tsintaksnya adalah gula untuk [123]T. Ini menciptakan array ukuran tetap, tetapi memungkinkan kompiler mengetahui berapa banyak elemen di dalamnya.
jimt
5
Saya kira memungkinkan array konstan akan memerlukan pembaruan ke sistem tipe. Kalau tidak, jika Anda mendefinisikan suatu fungsi, f(xs [5]int)Anda tidak akan tahu apakah array yang diteruskan adalah konstan atau dapat diubah.
Thomas Ahle
tks, saya punya masalah ketika saya mencoba untuk mengikat. Bergabunglah cannot use constants.FilesRequired (type [4]string) as type []string in argument to strings.Join
Eddy Hernandez
Terima kasih atas solusi slice. Keraguan: array itu sendiri tidak dapat diubah, bukan? Seseorang tidak dapat menambah atau menghapus elemen begitu array dibuat, bukan? Namun, saya dapat mengedit elemen array.
legends2k
@ legends2k Anda tidak dapat mengubah ukuran array, ya, tetapi Anda dapat memasukkan nilai lain ke dalam slotnya.
Denys Séguret
63

Dari Go Efektif :

Konstanta dalam Go hanya itu — konstan. Mereka dibuat pada waktu kompilasi, bahkan ketika didefinisikan sebagai fungsi lokal, dan hanya bisa berupa angka, string atau boolean. Karena pembatasan waktu kompilasi, ekspresi yang mendefinisikannya harus berupa ekspresi konstan, dapat dievaluasi oleh kompiler. Misalnya, 1 << 3 adalah ekspresi konstan, sedangkan math.Sin (math.Pi / 4) bukan karena fungsi memanggil ke math.Sin perlu terjadi pada saat run time.

Irisan dan array selalu dievaluasi selama runtime:

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

[...]memberitahu kompiler untuk mencari tahu panjang array itu sendiri. Irisan membungkus array dan lebih mudah untuk dikerjakan dalam banyak kasus. Alih-alih menggunakan konstanta hanya membuat variabel tidak dapat diakses ke paket lain dengan menggunakan huruf kecil pertama:

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

thisIsPrivatehanya tersedia dalam paket yang ditentukan. Jika Anda memerlukan akses baca dari luar, Anda dapat menulis fungsi pengambil sederhana (lihat Getters di golang ).

fasmat
sumber
12

Tidak ada konstanta array di Go.

Mengutip dari Spesifikasi Bahasa Go: Konstanta :

Ada konstanta boolean , konstanta Rune , konstanta bilangan bulat , konstanta floating-point , konstanta kompleks , dan konstanta string . Konstanta rune, integer, floating-point, dan kompleks secara kolektif disebut konstanta numerik .

Sebuah ekspresi Konstan (yang digunakan untuk menginisialisasi konstan) mungkin hanya berisi konstan operan dan dievaluasi pada waktu kompilasi.

Spesifikasi mencantumkan jenis konstanta yang berbeda. Perhatikan bahwa Anda dapat membuat dan menginisialisasi konstanta dengan ekspresi tipe konstan yang memiliki salah satu tipe yang diizinkan sebagai tipe yang mendasarinya . Misalnya ini valid:

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)
}

Output (coba di Go Playground ):

main.Myint 1
main.Myint 2

Jika Anda membutuhkan sebuah array, itu hanya bisa berupa variabel, tetapi bukan konstanta.

Saya merekomendasikan artikel blog hebat ini tentang konstanta: Konstanta

icza
sumber
lalu bagaimana jika membutuhkan wadah dengan ukuran konstan?
@Atomic_alarm Bisakah Anda menguraikan?
icza
Adakah di dalam golang analog C-array?
@ Automic_alarm Ya, array memang ada di Go juga, mereka bukan ekspresi konstan, mereka dievaluasi saat runtime. Jadi konstanta tidak bisa dari tipe array, tetapi variabel bisa. Misalnya:var arr = [2]int{2, 3}
icza
3

Seperti yang telah disebutkan orang lain, tidak ada konstruksi Go resmi untuk ini. Yang paling dekat yang bisa saya bayangkan adalah fungsi yang mengembalikan sepotong. Dengan cara ini, Anda dapat menjamin bahwa tidak ada yang akan memanipulasi elemen slice asli (karena "hard-coded" ke dalam array).

Saya telah mempersingkat irisan Anda untuk membuatnya ... lebih pendek ...:

func GetLetterGoodness() []float32 {
    return [...]float32 { .0817,.0149,.0278,.0425,.1270,.0223 }
}
Paul
sumber
4
ini kedengarannya seperti cara terbaik untuk pergi, namun jenis func kembali tidak cocok. cannot use [6]string literal (type [6]string) as type []string in return argumentjadireturn []float32 { ... }
theRemix
@theRemix Tiga kemungkinan perbaikan: (1) hapus ...sehingga mendeklarasikan slice literal alih-alih array literal. (2) ubah tipe pengembalian ke [6]float32. (3) menetapkan ekspresi untuk variabel array, a := [...]float32 { (etc.) }dan mengembalikan sepotong semua elemen: return a[:]. (Array literal tidak dapat dialamatkan, saya tidak jelas mengapa.)
David Moles
Saya tidak yakin apa yang Anda maksud dengan jaminan. Sepertinya Anda mencoba memecahkan sesuatu dalam kode Anda yang mungkin diselesaikan dengan lebih baik dengan (unit-) tes.
Dynom