2013-04-27 2 views

ответ

7

Опираясь на ответ @Kevin Берка, строго говоря

a := [][]byte{{1, 2}, {3, 4}} 

является slice ломтиков. Который сильно отличается от array массивов.

Playground link

fmt.Println("Array of Arrays") 
a := [2][2]int{{0, 1}, {2, 3}} 
for i := 0; i < 2; i++ { 
    for j := 0; j < 2; j++ { 
     fmt.Printf("a[%d][%d] = %d at %p\n", i, j, a[i][j], &a[i][j]) 
    } 
} 

fmt.Println("Slice of Slices") 
b := [][]int{{0, 1}, {2, 3}} 
for i := 0; i < 2; i++ { 
    for j := 0; j < 2; j++ { 
     fmt.Printf("b[%d][%d] = %d at %p\n", i, j, b[i][j], &b[i][j]) 
    } 
} 

Внутри массив массивов просто непрерывный бит памяти, так что это весьма эффективно, в то время как ломтик ломтиков является более сложным. Каждый вспомогательный срез может быть другого размера и выделяется в другом месте. Заголовки срезов занимают дополнительную оперативную память и используют дополнительные каналы доступа.

Например, creating 100,000 3x3 array of arrays использует 5,03 МБ ОЗУ, тогда как creating 100,000 3x3 slices of slices использует 13,79 МБ ОЗУ.

Кусочек ломтиков гораздо более гибкий - каждая строка может иметь разный размер, но если вы просто хотите матрицу 2x2, то массив массивов - намного лучший выбор.

Другое отличие состоит в том, что срезы являются ссылочными типами - если вы передадите срез функции, вы будете изменять исходный срез в функции. Массивы не являются - если вы передаете один из функций, вы будете делать копию, которая может быть медленной или может быть тем, что вы хотите. Если вы хотите его изменить, передайте указатель.

Here is an example

func f1(a [2][2]int) { 
    fmt.Println("I'm a function modifying an array of arrays argument") 
    a[0][0] = 100 
} 

func f2(b [][]int) { 
    fmt.Println("I'm a function modifying an slice of slices argument") 
    b[0][0] = 100 
} 

func main() { 
    fmt.Println("Array of arrays") 
    a := [2][2]int{{0, 1}, {2, 3}} 
    fmt.Printf("Before %v\n", a) 
    f1(a) 
    fmt.Printf("After %v\n\n", a) 

    fmt.Println("Slice of slices") 
    b := [][]int{{0, 1}, {2, 3}} 
    fmt.Printf("Before %v\n", b) 
    f2(b) 
    fmt.Printf("After %v\n", b) 
} 

который печатает

Array of arrays 
Before [[0 1] [2 3]] 
I'm a function modifying an array of arrays argument 
After [[0 1] [2 3]] 

Slice of slices 
Before [[0 1] [2 3]] 
I'm a function modifying an slice of slices argument 
After [[100 1] [2 3]] 

В целом для одномерных вещей слайс почти всегда лучше, чем массив. Однако для многомерного фиксированного размера массивы массивов являются лучшим выбором.

6

Использовать вложенные скобки:

a := [][]byte{{1, 2}, {3, 4}} 
Смежные вопросы