Dichiarare un array costante


164

Ho provato:

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 }

Primo, la dichiarazione e l'inizializzazione funzionano bene, ma il secondo, il terzo e il quarto non funzionano. Come posso dichiarare e inizializzare const array di float?

Risposte:


232

Un array non è immutabile per natura; non puoi renderlo costante.

Il più vicino che puoi ottenere è:

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 }

Nota [...]invece di []: ti assicura di ottenere un array (di dimensioni fisse) anziché una sezione. Quindi i valori non sono fissi ma la dimensione è.


126
Solo per chiarimenti: la [...]Tsintassi è zucchero per [123]T. Crea un array di dimensioni fisse, ma consente al compilatore di capire quanti elementi ci sono.
jimt

5
Immagino che consentire array costanti richiederebbe aggiornamenti al sistema di tipi. Altrimenti se si definisse una funzione f(xs [5]int)non si saprebbe se l'array passato fosse costante o modificabile.
Thomas Ahle,

tks, ho problemi quando provo a stringhecannot use constants.FilesRequired (type [4]string) as type []string in argument to strings.Join
Eddy Hernandez il

Grazie per la soluzione slice. Dubbio: un array stesso è immutabile, giusto? Non è possibile aggiungere o rimuovere elementi una volta creato un array, no? Posso, tuttavia, modificare gli elementi dell'array.
legends2k,

@ legends2k Non è possibile modificare la dimensione dell'array, sì, ma è possibile inserire altri valori negli slot.
Denys Séguret,

63

Da Go efficace :

Le costanti in Go sono proprio questo: costanti. Vengono creati in fase di compilazione, anche se definiti come locali nelle funzioni, e possono essere solo numeri, stringhe o valori booleani. A causa della limitazione del tempo di compilazione, le espressioni che le definiscono devono essere espressioni costanti, valutabili dal compilatore. Ad esempio, 1 << 3 è un'espressione costante, mentre math.Sin (math.Pi / 4) non è perché la chiamata di funzione a math.Sin deve avvenire in fase di esecuzione.

Fette e matrici vengono sempre valutate durante il runtime:

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

[...]dice al compilatore di capire la lunghezza dell'array stesso. Le fette avvolgono gli array e nella maggior parte dei casi sono più facili da lavorare. Invece di usare le costanti, rendi inaccessibili le variabili ad altri pacchetti usando una prima lettera minuscola:

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

thisIsPrivateè disponibile solo nel pacchetto definito. Se hai bisogno di un accesso in lettura dall'esterno, puoi scrivere una semplice funzione getter (vedi Getter in golang ).


12

In Go non esiste una costante di array.

Citando dal Go Specifica di lingua: Costanti :

Ci sono costanti booleane , costanti runiche , costanti intere , le costanti a virgola mobile , costanti complesse e costanti stringa . Le costanti di rune, numeri interi, a virgola mobile e complesse sono collettivamente chiamate costanti numeriche .

Un'espressione Constant (che viene utilizzato per inizializzare una costante) può contenere solo costanti operandi e vengono valutati in fase di compilazione.

La specifica elenca i diversi tipi di costanti. Si noti che è possibile creare e inizializzare costanti con espressioni costanti di tipi che hanno uno dei tipi consentiti come tipo sottostante . Ad esempio questo è valido:

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 (provalo sul Go Playground ):

main.Myint 1
main.Myint 2

Se hai bisogno di un array, può essere solo una variabile, ma non una costante.

Consiglio questo fantastico articolo di blog sulle costanti: Costanti


allora cosa fare se è necessario un contenitore di dimensioni costanti?

@Atomic_alarm Puoi approfondire per favore?
Icza,

Esiste se nell'array C analogico golang?

@Atomic_alarm Sì, anche in Go esistono matrici, non sono espressioni costanti, ma vengono valutate in fase di esecuzione. Quindi una costante non può essere di tipo array, ma una variabile può. Ad esempio:var arr = [2]int{2, 3}
Icza,

3

Come altri hanno già detto, non esiste un costrutto Go ufficiale per questo. Il più vicino che posso immaginare sarebbe una funzione che restituisce una sezione. In questo modo, è possibile garantire che nessuno manipolerà gli elementi della porzione originale (poiché è "hard-coded" nell'array).

Ho abbreviato la tua fetta per renderla ... più breve ...:

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

4
questo sembra il modo migliore di procedere, tuttavia il tipo di ritorno della funzione non corrisponde. cannot use [6]string literal (type [6]string) as type []string in return argumentcosìreturn []float32 { ... }
theRemix

@theRemix Tre possibili correzioni: (1) rimuovere in ...modo da dichiarare un valore letterale slice anziché un valore letterale array. (2) cambia il tipo di ritorno in [6]float32. (3) assegnare l'espressione di una variabile di matrice, a := [...]float32 { (etc.) }e restituire la fetta di tutti gli elementi: return a[:]. (I letterali delle matrici non sono indirizzabili, non sono chiaro il perché.)
David Moles,

Non sono sicuro di cosa significhi garanzie. Sembra che tu provi a risolvere qualcosa nel tuo codice che è probabilmente risolto meglio con (unit-) test.
Dynom,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.