Não existe uma forma mais concisa, o que você fez é da maneira "certa"; porque as fatias são sempre unidimensionais, mas podem ser compostas para construir objetos de dimensões superiores. Veja esta pergunta para mais detalhes: Go: Como é a representação da memória de um array bidimensional .
Uma coisa que você pode simplificar é usar a for range
construção:
a := make([][]uint8, dy)
for i := range a {
a[i] = make([]uint8, dx)
}
Observe também que se você inicializar sua fatia com um literal composto , você obterá isso "gratuitamente", por exemplo:
a := [][]uint8{
{0, 1, 2, 3},
{4, 5, 6, 7},
}
fmt.Println(a) // Output is [[0 1 2 3] [4 5 6 7]]
Sim, isso tem seus limites, pois aparentemente você tem que enumerar todos os elementos; mas existem alguns truques, nomeadamente você não tem que enumerar todos os valores, apenas aqueles que não são os valores zero do tipo de elemento da fatia. Para obter mais detalhes sobre isso, consulte Itens codificados na inicialização do array golang .
Por exemplo, se você deseja uma fatia em que os primeiros 10 elementos são zeros e, em seguida, segue 1
e 2
, pode ser criada assim:
b := []uint{10: 1, 2}
fmt.Println(b) // Prints [0 0 0 0 0 0 0 0 0 0 1 2]
Observe também que, se você usar matrizes em vez de fatias , elas podem ser criadas com muita facilidade:
c := [5][5]uint8{}
fmt.Println(c)
O resultado é:
[[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]]
No caso de arrays, você não precisa iterar sobre o array "externo" e inicializar os arrays "internos", pois os arrays não são descritores, mas valores. Veja a postagem do blog Matrizes, fatias (e strings): A mecânica de 'anexar' para mais detalhes.
Experimente os exemplos no Go Playground .
cannot use [5][2]string literal (type [5][2]string) as type [][]string in field value
quando tento atribuir o array ao que acho que estou dizendo a Go é um slice.Existem duas maneiras de usar fatias para criar uma matriz. Vamos dar uma olhada nas diferenças entre eles.
Primeiro método:
Segundo método:
Em relação ao primeiro método, fazer
make
chamadas sucessivas não garante que você acabará com uma matriz contígua, portanto, você pode ter a matriz dividida na memória. Vamos pensar em um exemplo com duas rotinas Go que podem causar isso:make([][]int, n)
para obter memória alocadamatrix
, obtendo um pedaço de memória de 0x000 a 0x07F.make([]int, m)
, indo de 0x080 a 0x0FF.make
(para seus próprios propósitos) e vai de 0x100 a 0x17F (próximo à primeira linha da rotina # 0).make([]int, m)
correspondente à segunda iteração do loop e vai de 0x180 a 0x1FF para a segunda linha. Neste ponto, já temos duas linhas divididas.Com o segundo método, a rotina faz
make([]int, n*m)
para obter toda a matriz alocada em um único slice, garantindo a contiguidade. Depois disso, um loop é necessário para atualizar os ponteiros da matriz para os sub-segmentos correspondentes a cada linha.Você pode brincar com o código mostrado acima no Go Playground para ver a diferença na memória atribuída usando os dois métodos. Observe que usei
runtime.Gosched()
apenas com o objetivo de ceder o processador e forçar o escalonador a mudar para outra rotina.Qual usar? Imagine o pior caso com o primeiro método, ou seja, cada linha não é a próxima na memória a outra linha. Então, se seu programa itera através dos elementos da matriz (para lê-los ou gravá-los), provavelmente haverá mais perdas de cache (portanto, latência mais alta) em comparação com o segundo método por causa da pior localidade dos dados. Por outro lado, com o segundo método pode não ser possível obter um único pedaço de memória alocado para a matriz, por causa da fragmentação da memória (pedaços espalhados por toda a memória), embora teoricamente possa haver memória livre suficiente para isso .
Portanto, a menos que haja muita fragmentação de memória e a matriz a ser alocada seja grande o suficiente, você sempre desejaria usar o segundo método para obter vantagem da localidade dos dados.
fonte
Nas respostas anteriores não consideramos a situação em que o comprimento inicial é desconhecido. Para este caso, você pode usar a seguinte lógica para criar a matriz
https://play.golang.org/p/pHgggHr4nbB
fonte