пятница, 25 января 2019 г.

Эффективный Go: двумерные срезы

Массивы и срезы в Go являются одномерными. Чтобы создать эквивалент двумерного массива или среза, необходимо определить массив массивов или срез срезов, например:

// 3x3 массив, на самом деле массив массивов.
type Transform [3][3]float64  

// Срез byte срезов.
type LinesOfText [][]byte     

Поскольку срезы имеют переменную длину, возможно иметь каждый внутренний срез с разной длиной. Это может быть обычной ситуацией, как в нашем LinesOfText примере: каждая строка имеет независимую длину.

text := LinesOfText{
    []byte("Now is the time"),
    []byte("for all good gophers"),
    []byte("to bring some fun to the party."),
}

Иногда необходимо выделить двумерный срез - ситуация, которая может возникнуть, когда, например, происходит обработка сканированных строк пикселей. Есть два способа добиться этого. Одним из них является выделение каждого среза независимо; другой состоит в том, чтобы выделить один массив и указать отдельные срезы в нем. Какой из них использовать, зависит от вашего приложения. Если срезы могут расти или сокращаться, они должны быть выделены независимо чтобы избежать перезаписи следующей строки; если нет, то может быть более эффективным построение объекта с однократной аллокацией. Вот эскизы двух методов. Первый способ, строка за раз:

// Аллоцируем срез самого верхнего уровня.
// Один ряд на каждый элемент y.
picture := make([][]uint8, YSize) 

// Цикл по рядам, аллоцируем срез для каждого ряда.
for i := range picture {
    picture[i] = make([]uint8, XSize)
}

И второй способ - как одно аллоцирование, разбитое на строки:

// Аллоцируем срез самого верхнего уровня, 
// такой же как и прежде.
// Один ряд на каждый элемент y.
picture := make([][]uint8, YSize) 

// Аллоцируем один большой срез для хранения всех пикселей.
// Имеем тип []uint8 даже хотя изображение это [][]uint8.
pixels := make([]uint8, XSize*YSize) 

// Цикл по рядам, создаем срез каждого ряда 
// от начала среза оставшихся пикселей.
for i := range picture {
    picture[i], pixels = pixels[:XSize], pixels[XSize:]
}


Читайте также:


Комментариев нет:

Отправить комментарий