Declarar una matriz constante

164

Yo he tratado:

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 }

Primero, la declaración y la inicialización funcionan bien, pero el segundo, tercero y cuarto no funcionan. ¿Cómo puedo declarar e inicializar la matriz constante de flotadores?

demas
fuente

Respuestas:

232

Una matriz no es inmutable por naturaleza; No puedes hacerlo constante.

Lo más cercano que puede obtener es:

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 }

Tenga [...]en cuenta que en lugar de []: garantiza que obtenga una matriz (tamaño fijo) en lugar de un segmento. Entonces los valores no son fijos pero el tamaño sí lo es.

Denys Séguret
fuente
126
Solo para aclarar: la [...]Tsintaxis es para azúcar [123]T. Crea una matriz de tamaño fijo, pero permite que el compilador descubra cuántos elementos contiene.
jimt
55
Supongo que permitir matrices constantes requeriría actualizaciones para el sistema de tipos. De lo contrario, si definió una función f(xs [5]int), no sabría si la matriz aprobada fue constante o mutable.
Thomas Ahle
tks, tengo problemas cuando trato de cuerdascannot use constants.FilesRequired (type [4]string) as type []string in argument to strings.Join
Eddy Hernández
Gracias por la solución de corte. Duda: una matriz en sí misma es inmutable, ¿verdad? Uno no puede agregar o eliminar elementos una vez que se crea una matriz, ¿no? Sin embargo, puedo editar los elementos de la matriz.
legends2k
@ legends2k No puede cambiar el tamaño de la matriz, sí, pero puede poner otros valores en sus ranuras.
Denys Séguret
63

De Go eficaz :

Las constantes en Go son solo eso, constantes. Se crean en tiempo de compilación, incluso cuando se definen como locales en funciones, y solo pueden ser números, cadenas o booleanos. Debido a la restricción de tiempo de compilación, las expresiones que las definen deben ser expresiones constantes, evaluables por el compilador. Por ejemplo, 1 << 3 es una expresión constante, mientras que math.Sin (math.Pi / 4) no se debe a que la llamada a la función math.Sin debe suceder en tiempo de ejecución.

Los segmentos y las matrices siempre se evalúan durante el tiempo de ejecución:

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

[...]le dice al compilador que calcule la longitud de la matriz en sí. Las rebanadas envuelven matrices y son más fáciles de trabajar en la mayoría de los casos. En lugar de usar constantes, simplemente haga que las variables sean inaccesibles para otros paquetes usando una primera letra minúscula:

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

thisIsPrivateestá disponible solo en el paquete que está definido. Si necesita acceso de lectura desde el exterior, puede escribir una función getter simple (vea Getters en golang ).

fasmat
fuente
12

No existe la constante de matriz en Go.

Citando desde el Go Idioma Especificación: Constantes :

Hay constantes booleanas , constantes runa , constantes enteras , las constantes de punto flotante , constantes complejas , y las constantes de cadena . Runa, entero, coma flotante y constantes complejas se denominan colectivamente constantes numéricas .

Una expresión constante (que se usa para inicializar una constante) puede contener solo operandos constantes y se evalúa en tiempo de compilación.

La especificación enumera los diferentes tipos de constantes. Tenga en cuenta que puede crear e inicializar constantes con expresiones constantes de tipos que tengan uno de los tipos permitidos como tipo subyacente . Por ejemplo, esto es 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)
}

Salida (pruébalo en Go Playground ):

main.Myint 1
main.Myint 2

Si necesita una matriz, solo puede ser una variable, pero no una constante.

Recomiendo este gran artículo de blog sobre constantes: Constantes

icza
fuente
entonces, ¿qué hacer si necesita un contenedor con tamaño constante?
@Atomic_alarm ¿Puedes dar más detalles por favor?
icza
¿Existe ya en el análogo golang C-array?
@Atomic_alarm Sí, las matrices también existen en Go, simplemente no son expresiones constantes, se evalúan en tiempo de ejecución. Por lo tanto, una constante no puede ser de un tipo de matriz, pero una variable sí. Por ejemplo:var arr = [2]int{2, 3}
icza
3

Como otros han mencionado, no hay una construcción oficial de Go para esto. Lo más cercano que puedo imaginar sería una función que devuelva un segmento. De esta manera, puede garantizar que nadie manipulará los elementos del segmento original (ya que está "codificado" en la matriz).

He acortado tu porción para que sea ... más corta ...:

func GetLetterGoodness() []float32 {
    return [...]float32 { .0817,.0149,.0278,.0425,.1270,.0223 }
}
Pablo
fuente
44
Esto suena como el mejor camino a seguir, sin embargo, el tipo de retorno de func no coincide. cannot use [6]string literal (type [6]string) as type []string in return argumentsoreturn []float32 { ... }
theRemix
@theRemix Tres posibles soluciones: (1) eliminar ...para declarar un literal de corte en lugar de un literal de matriz. (2) cambie el tipo de retorno a [6]float32. (3) asignar la expresión a una variable de matriz, a := [...]float32 { (etc.) }y devolver la rebanada de todos los elementos: return a[:]. (Los literales de matriz no son direccionables, no estoy claro por qué.)
David Moles
No estoy seguro de a qué te refieres. Parece que intenta resolver algo en su código que probablemente se resuelva mejor con pruebas (unitarias).
Dynom