2016-10-16 6 views
1

Глядя на документации для golang's 2D slices и не может понять синтаксис, используемый в предыдущем примере:Как эта «общая идиома» действительно работает?

func main() { 
    XSize := 5 
    YSize := 5 

    // Allocate the top-level slice, the same as before. 
    picture := make([][]uint8, YSize) // One row per unit of y. 

    // Allocate one large slice to hold all the pixels. 
    pixels := make([]uint8, XSize*YSize) // Has type []uint8 even though picture is [][]uint8. 

    // Loop over the rows, slicing each row from the front of the remaining pixe ls slice. 
    for i := range picture { 
     picture[i], pixels = pixels[:XSize], pixels[XSize:] 
    } 
} 

Я нашел change request где это было добавлен к документации и изменение автора этого нормальному/легко понять код:

// Loop over the rows, slicing each row. 
for i := range picture { 
    picture[i] = pixels[i*XSize:(i+1)*XSize] 

Однако есть следующий комментарий:

отлично. еще одна общая идиома, чтобы избежать математику:

picture[i], pixels = pixels[:XSize], pixels[XSize:]

Мой вопрос, как же выше достичь такой же, как «избежать математике» метод? Некоторые документы о том, что происходит, были бы замечательными.

ответ

5

Это:

picture[i], pixels = pixels[:XSize], pixels[XSize:] 

Является ли кортеж assignment. Он присваивает значение picture[i] и значение pixels. Значения, назначенные по порядку, - pixels[:XSize] и pixels[XSize:].

Назначение продолжается в два этапа. Во-первых, операнды index expressions и pointer indirections (включая неявные указатели указателя в selectors) слева, а выражения справа - evaluated in the usual order. Во-вторых, назначения выполняются в порядке слева направо.

Что здесь происходит в том, что, когда начинается цикл (i = 0), первый элемент picture (в первой строке) присваивается значение ломтика быть первыми XSize элементы в pixels, и кусочек pixels является resliced ​​так его первым элементом будет XSizeth элемент +1.

Таким образом, в следующей итерации picture[i] будет второй элементом в picture (2-й строке), и снова, первые XSize элементы из pixels будут установлены в нем как срез. Но так как в предыдущей итерации мы повторно произвели pixels, на каждой итерации его первые XSize элементы будут следующими строками.

+0

Awe right. Полностью имеет смысл.'(picture [i], pixels) = (пиксели [: XSize], пиксели [XSize:])'. Просто не видел этого. – Jonathan

2

Этот кортеж пример присваивания можно переписать так:

for i := range picture { 
    picture[i]= pixels[:XSize] 
    pixels = pixels[XSize:] 
} 

Это теперь легче увидеть, что картина это первый XSIZE товар пикселей.

И пикселеймодифицируется на каждом цикле и капли первые XSIZE пунктов.

 Смежные вопросы

  • Нет связанных вопросов^_^