No hay una forma más concisa, lo que hiciste es la forma "correcta"; porque los cortes son siempre unidimensionales pero pueden estar compuestos para construir objetos de dimensiones superiores. Consulte esta pregunta para obtener más detalles: Ir: ¿Cómo es la representación de memoria de matriz bidimensional .
Una cosa que puede simplificar es usar la for range
construcción:
a := make([][]uint8, dy)
for i := range a {
a[i] = make([]uint8, dx)
}
También tenga en cuenta que si inicializa su segmento con un literal compuesto , lo obtiene "gratis", por ejemplo:
a := [][]uint8{
{0, 1, 2, 3},
{4, 5, 6, 7},
}
fmt.Println(a) // Output is [[0 1 2 3] [4 5 6 7]]
Sí, esto tiene sus límites ya que aparentemente hay que enumerar todos los elementos; pero hay algunos trucos, es decir, no es necesario enumerar todos los valores, solo los que no son los valores cero del tipo de elemento del segmento. Para obtener más detalles sobre esto, consulte Elementos con clave en la inicialización de la matriz golang .
Por ejemplo, si desea un segmento donde los primeros 10 elementos son ceros, y luego sigue 1
y 2
, se puede crear así:
b := []uint{10: 1, 2}
fmt.Println(b) // Prints [0 0 0 0 0 0 0 0 0 0 1 2]
También tenga en cuenta que si usa matrices en lugar de porciones , se puede crear muy fácilmente:
c := [5][5]uint8{}
fmt.Println(c)
La salida es:
[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
En el caso de matrices, no es necesario iterar sobre la matriz "externa" e inicializar las matrices "internas", ya que las matrices no son descriptores sino valores. Consulte la publicación de blog Arrays, slices (y strings): The Mechanics of 'append' para obtener más detalles.
Pruebe los ejemplos en Go Playground .
cannot use [5][2]string literal (type [5][2]string) as type [][]string in field value
cuando trato de asignar la matriz a lo que supongo que le estoy diciendo a Go es una porción.Hay dos formas de utilizar porciones para crear una matriz. Echemos un vistazo a las diferencias entre ellos.
Primer método:
Segundo método:
En lo que respecta al primer método, hacer
make
llamadas sucesivas no garantiza que terminará con una matriz contigua, por lo que puede tener la matriz dividida en la memoria. Pensemos en un ejemplo con dos rutinas de Go que podrían causar esto:make([][]int, n)
para obtener memoria asignada paramatrix
obtener una parte de la memoria de 0x000 a 0x07F.make([]int, m)
, pasando de 0x080 a 0x0FF.make
(para sus propios fines) y pasa de 0x100 a 0x17F (justo al lado de la primera fila de la rutina # 0).make([]int, m)
corresponde a la segunda iteración del ciclo y pasa de 0x180 a 0x1FF para la segunda fila. En este punto, ya tenemos dos filas divididas.Con el segundo método, la rutina hace
make([]int, n*m)
que toda la matriz se asigne en un solo segmento, lo que garantiza la contigüidad. Después de eso, se necesita un bucle para actualizar los punteros de la matriz a las sublices correspondientes a cada fila.Puedes jugar con el código que se muestra arriba en Go Playground para ver la diferencia en la memoria asignada usando ambos métodos. Tenga en cuenta que utilicé
runtime.Gosched()
solo con el propósito de ceder el procesador y forzar al programador a cambiar a otra rutina.Cual usar? Imagine el peor de los casos con el primer método, es decir, cada fila no es la siguiente en la memoria a otra fila. Luego, si su programa itera a través de los elementos de la matriz (para leerlos o escribirlos), probablemente habrá más fallas de caché (por lo tanto, mayor latencia) en comparación con el segundo método debido a una peor localidad de datos. Por otro lado, con el segundo método puede que no sea posible obtener una sola pieza de memoria asignada para la matriz, debido a la fragmentación de la memoria (fragmentos repartidos por toda la memoria), aunque teóricamente puede haber suficiente memoria libre para ello. .
Por lo tanto, a menos que haya mucha fragmentación de memoria y la matriz a asignar sea lo suficientemente grande, siempre querrá usar el segundo método para aprovechar la localidad de los datos.
fuente
En respuestas anteriores no consideramos la situación cuando se desconoce la longitud inicial. Para este caso, puede usar la siguiente lógica para crear una matriz
https://play.golang.org/p/pHgggHr4nbB
fuente