Declarar uma matriz constante

164

Eu tentei:

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 }

Primeiro, a declaração e a inicialização funcionam bem, mas a segunda, terceira e quarta não funcionam. Como posso declarar e inicializar const array de carros alegóricos?

demas
fonte

Respostas:

232

Uma matriz não é imutável por natureza; você não pode torná-lo constante.

O mais próximo que você pode chegar é:

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 }

Observe o em [...]vez de []: garante que você obtenha uma matriz (tamanho fixo) em vez de uma fatia. Portanto, os valores não são fixos, mas o tamanho é.

Denys Séguret
fonte
126
Apenas para esclarecimento: a [...]Tsintaxe é para o açúcar [123]T. Ele cria uma matriz de tamanho fixo, mas permite que o compilador descubra quantos elementos estão nela.
jimt
5
Eu acho que permitir matrizes constantes exigiria atualizações no sistema de tipos. Caso contrário, se você definisse uma função f(xs [5]int), não saberia se a matriz passada era constante ou mutável.
Thomas Ahle
Eu tenho problemas quando tento stringscannot use constants.FilesRequired (type [4]string) as type []string in argument to strings.Join
Eddy Hernandez
Obrigado pela solução fatia. Dúvida: uma matriz em si é imutável, certo? Não se pode adicionar ou remover elementos depois que uma matriz é criada, não? No entanto, posso editar os elementos da matriz.
Legends2k
@ legends2k Não é possível alterar o tamanho da matriz, sim, mas você pode colocar outros valores em seus slots.
Denys Séguret
63

Do Effective Go :

As constantes em Go são exatamente isso - constantes. Eles são criados em tempo de compilação, mesmo quando definidos como locais em funções, e podem ser apenas números, seqüências de caracteres ou booleanos. Devido à restrição de tempo de compilação, as expressões que os definem devem ser expressões constantes, avaliadas pelo compilador. Por exemplo, 1 << 3 é uma expressão constante, enquanto math.Sin (math.Pi / 4) não é porque a chamada de função para math.Sin precisa acontecer em tempo de execução.

Fatias e matrizes são sempre avaliadas durante o tempo de execução:

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

[...]diz ao compilador para descobrir o comprimento da própria matriz. As fatias envolvem matrizes e são mais fáceis de trabalhar na maioria dos casos. Em vez de usar constantes, apenas torne as variáveis ​​inacessíveis para outros pacotes usando uma primeira letra minúscula:

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

thisIsPrivateestá disponível apenas no pacote que está definido. Se você precisar de acesso de leitura de fora, poderá escrever uma função getter simples (consulte Getters em golang ).

fasmat
fonte
12

Não existe constante de matriz no Go.

Citando a partir da especificação de idioma Go: Constantes :

Existem constantes booleanos , constantes rune , constantes inteiras , constantes de ponto flutuante , constantes complexas , e as constantes de cadeia . Constantes de runa, número inteiro, ponto flutuante e complexo são coletivamente chamadas de constantes numéricas .

Uma expressão constante (que é usada para inicializar uma constante) pode conter apenas operandos constantes e é avaliada em tempo de compilação.

A especificação lista os diferentes tipos de constantes. Observe que você pode criar e inicializar constantes com expressões constantes de tipos com um dos tipos permitidos como o tipo subjacente . Por exemplo, isso é válido:

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

Saída (experimente no Go Playground ):

main.Myint 1
main.Myint 2

Se você precisar de uma matriz, ela pode ser apenas uma variável, mas não uma constante.

Eu recomendo este excelente artigo do blog sobre constantes: Constantes

icza
fonte
então o que fazer se precisar de um contêiner com tamanho constante?
@Atomic_alarm Você pode elaborar, por favor?
icza 31/03
Existe se no C-array analógico golang?
@Atomic_alarm Sim, existem matrizes no Go também, elas não são expressões constantes, são avaliadas em tempo de execução. Portanto, uma constante não pode ser de um tipo de matriz, mas uma variável pode. Por exemplo:var arr = [2]int{2, 3}
icza
3

Como outros já mencionaram, não existe uma construção Go oficial para isso. O mais próximo que posso imaginar seria uma função que retorne uma fatia. Dessa forma, você pode garantir que ninguém manipule os elementos da fatia original (pois ela é "codificada" na matriz).

Reduzi sua fatia para torná-la ... mais curta ...:

func GetLetterGoodness() []float32 {
    return [...]float32 { .0817,.0149,.0278,.0425,.1270,.0223 }
}
Paulo
fonte
4
isso soa como o melhor caminho a seguir, no entanto, o tipo de retorno func não corresponde. cannot use [6]string literal (type [6]string) as type []string in return argumentassimreturn []float32 { ... }
theRemix
@theRemix Três correções possíveis: (1) remova ...para declarar uma fatia literal em vez de uma matriz literal. (2) altere o tipo de retorno para [6]float32. (3) atribuir a expressão para uma variável de matriz, a := [...]float32 { (etc.) }e voltar a fatia de todos os elementos: return a[:]. (Literais de matriz não são endereçáveis, eu não estou claro por que.)
David Moles
Não tenho certeza do que você quer dizer com isso. Parece que você tenta resolver algo no seu código que provavelmente foi resolvido melhor com testes (unit-).
Dynom