Tidak ada cara yang lebih ringkas, apa yang Anda lakukan adalah cara yang "benar"; karena irisan selalu satu dimensi tetapi dapat disusun untuk membangun objek berdimensi lebih tinggi. Lihat pertanyaan ini untuk lebih jelasnya: Pergi: Bagaimana representasi memori array dua dimensi .
Satu hal yang dapat Anda sederhanakan adalah dengan menggunakan for range
konstruksi:
a := make([][]uint8, dy)
for i := range a {
a[i] = make([]uint8, dx)
}
Perhatikan juga bahwa jika Anda menginisialisasi potongan Anda dengan literal komposit , Anda mendapatkan ini secara "gratis", misalnya:
a := [][]uint8{
{0, 1, 2, 3},
{4, 5, 6, 7},
}
fmt.Println(a) // Output is [[0 1 2 3] [4 5 6 7]]
Ya, ini ada batasnya karena Anda harus menghitung semua elemen; tetapi ada beberapa trik, yaitu Anda tidak harus menghitung semua nilai, hanya nilai yang bukan nilai nol dari jenis elemen potongan. Untuk detail selengkapnya tentang ini, lihat Item yang dimasukkan dalam inisialisasi larik golang .
Misalnya jika Anda menginginkan potongan di mana 10 elemen pertama adalah nol, lalu mengikuti 1
dan 2
, itu bisa dibuat seperti ini:
b := []uint{10: 1, 2}
fmt.Println(b) // Prints [0 0 0 0 0 0 0 0 0 0 1 2]
Perhatikan juga bahwa jika Anda menggunakan array, bukan irisan , ini dapat dibuat dengan sangat mudah:
c := [5][5]uint8{}
fmt.Println(c)
Outputnya adalah:
[[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]]
Dalam kasus array, Anda tidak perlu mengulang array "luar" dan menginisialisasi array "dalam", karena array bukanlah deskriptor tetapi nilai. Lihat entri blog Array, irisan (dan string): Mekanisme 'tambahkan' untuk detail selengkapnya.
Coba contoh di Go Playground .
cannot use [5][2]string literal (type [5][2]string) as type [][]string in field value
ketika saya mencoba untuk menetapkan array ke apa yang saya kira saya katakan Go is a slice.Ada dua cara menggunakan irisan untuk membuat matriks. Mari kita lihat perbedaan di antara keduanya.
Metode pertama:
Metode kedua:
Berkenaan dengan metode pertama, melakukan
make
panggilan berturut-turut tidak memastikan bahwa Anda akan berakhir dengan matriks yang berdekatan, jadi Anda mungkin memiliki matriks yang terbagi dalam memori. Mari kita pikirkan contoh dengan dua rutinitas Go yang dapat menyebabkan ini:make([][]int, n)
untuk mendapatkan memori yang dialokasikanmatrix
, mendapatkan bagian memori dari 0x000 hingga 0x07F.make([]int, m)
, dari 0x080 ke 0x0FF.make
(untuk tujuannya sendiri) dan berpindah dari 0x100 ke 0x17F (tepat di sebelah baris pertama rutinitas # 0).make([]int, m)
sesuai dengan iterasi loop kedua dan beralih dari 0x180 ke 0x1FF untuk baris kedua. Pada titik ini, kami sudah mendapatkan dua baris yang terbagi.Dengan metode kedua, rutin dilakukan
make([]int, n*m)
untuk mendapatkan semua matriks dialokasikan dalam satu bagian, memastikan kedekatan. Setelah itu, diperlukan perulangan untuk memperbarui penunjuk matriks ke subleks yang sesuai dengan setiap baris.Anda dapat bermain dengan kode yang ditunjukkan di atas di Go Playground untuk melihat perbedaan dalam memori yang ditetapkan dengan menggunakan kedua metode tersebut. Perhatikan bahwa saya
runtime.Gosched()
hanya menggunakan dengan tujuan menghasilkan prosesor dan memaksa penjadwal untuk beralih ke rutinitas lain.Yang mana yang akan digunakan? Bayangkan kasus terburuk dengan metode pertama, yaitu setiap baris tidak berada di memori berikutnya ke baris lain. Kemudian, jika program Anda melakukan iterasi melalui elemen matriks (untuk membaca atau menulisnya), mungkin akan ada lebih banyak cache yang hilang (karenanya latensi lebih tinggi) dibandingkan dengan metode kedua karena lokalitas data yang lebih buruk. Di sisi lain, dengan metode kedua, tidak mungkin mendapatkan satu bagian memori yang dialokasikan untuk matriks, karena fragmentasi memori (potongan tersebar di seluruh memori), meskipun secara teoritis mungkin ada cukup memori kosong untuk itu. .
Oleh karena itu, kecuali jika ada banyak fragmentasi memori dan matriks yang akan dialokasikan cukup besar, Anda akan selalu ingin menggunakan metode kedua untuk memanfaatkan lokalitas data.
sumber
Dalam jawaban sebelumnya kami tidak mempertimbangkan situasi ketika panjang awalnya tidak diketahui. Untuk kasus ini, Anda dapat menggunakan logika berikut untuk membuat matriks
https://play.golang.org/p/pHgggHr4nbB
sumber