2016-06-23 28 views
7

Vorrei creare una mappa costante come il seguente:Perché Golang non consente le mappe const?

const (
    running = map[string]string{ 
     "one": "ONE", 
     "two": "TWO", 
    } 
) 

però ogni volta che ricevo il seguente errore:

const initializer map[string]string literal is not a constant

perché è questo il caso, perché non lo fa Golang trattarli come qualsiasi altra variabile?

+1

Penso che la risposta alla domanda ** perché ** è che gli autori di go giudicano che la complessità dell'implementazione non vale i benefici che porta. – ain

+3

Possibile duplicato di [dichiarare un array costante] (http://stackoverflow.com/questions/13137463/declare-a-constant-array) – icza

+0

Penso che sia possibile una mappa immutabile. Non è possibile dichiarare una mappa immutabile solo perché una mappa in lingua Go è una costruzione linguistica ma non un'implementazione di alcune interfacce 'Mappa'. Cioè, non puoi implementare la tua mappa che sia compatibile (tramite le interfacce) con la mappa Go interna. – mezoni

risposta

7

Da https://golang.org/ref/spec#Constants:

A constant value is represented by a rune, integer, floating-point, imaginary, or string literal, an identifier denoting a constant, a constant expression, a conversion with a result that is a constant, or the result value of some built-in functions such as unsafe.Sizeof applied to any value, cap or len applied to some expressions, real and imag applied to a complex constant and complex applied to numeric constants.

tl; dr unici tipi numerici, stringhe e bools possono essere costanti, array fette e mappe non sono un tipo numerico.

0

La mia opinione è che questa decisione era puramente pragmatica: Go è un linguaggio molto realistico (al contrario di altre — lingue), e una proprietà interessante di alcune mappe del mondo reale le implementazioni sono che il semplice accesso ad esse per la lettura potrebbe aggiornare la loro rappresentazione interna (!). Per esempio, potrebbero raccogliere e memorizzare alcune statistiche sul loro utilizzo, oppure potrebbero riequilibrare un albero sottostante che contiene i bucket di valore ecc. Consentire una "mappa const" di esistere significherebbe esplicitamente un insieme di complicati vincoli su di esso nella specifica del linguaggio — probabilmente richiedono implementazioni per avere due implementazioni di mappe.

Puoi anche provare a guardarlo da un'altra angolazione: considera una costante di stringa. Tale cosa potrebbe essere facilmente incorporata nella sezione .rodata del binario risultante ed essere effettivamente rappresentata dall'indirizzo di quei dati in memoria (beh, le stringhe in Go sono più complicate ma ignoriamo quel dettaglio). Cioè, una stringa costante può essere veramente "statica": è solo una serie di byte R/O statici nella memoria — così semplice. Al contrario, una mappa è una bestia molto complicata alimentata da un macchinario complesso e ogni mappa è un oggetto complesso speciale istanziato in fase di runtime. Ecco perché non puoi nemmeno dichiarare una mappa e usarla: devi make() prima come —, proprio come i canali, e per lo stesso motivo.

Ancora una volta, è possibile eseguire alcune modifiche per supportare mappe costanti. Supponiamo che un'implementazione possa ordinare le chiavi della mappa in primo piano, serializzarla (con valori) in un'area contigua di dati di R/O e quindi utilizzare la ricerca binaria in runtime per visualizzare i valori. Sarebbe tristemente inefficace per le mappe di grandi dimensioni/alcuni modelli chiave, ma funzionerebbe presumibilmente. Tuttavia, sarebbe un'implementazione di mappe specializzate completamente diversa da quella "normale". Penso che Go Devs abbia deciso che il compromesso non vale i benefici possibili.

due note followup:

  • Come si può vedere, è possibile in modo relativamente facile emulare una mappa in sola lettura: avere una fetta letterale di alcuni tipi struct incorporamento entrambe le chiavi e valori, presorted sui tasti, e avvolgerlo in una funzione che esegue una ricerca binaria sulla chiave.

  • preferisco considerare le costanti di andare un po 'come macro in un C-come lingue: sono senza tipo e sento come essere testuali (non sono ma sto parlando di sentirsi dopo tutto); -)

    Assicurati di leggere this per una panoramica eccezionale.