2013-09-29 2 views
21

Я новичок в Go и пытаюсь написать приложение, которое читает RPM-файлы. Начало каждого блока имеет магический шар [4]byte.В Golang как вы преобразовываете срез в массив

Вот моя структура

type Lead struct { 
    Magic  [4]byte 
    Major, Minor byte 
    Type   uint16 
    Arch   uint16 
    Name   string 
    OS   uint16 
    SigType  uint16 
} 

Я пытаюсь сделать следующее:

lead := Lead{} 
lead.Magic = buffer[0:4] 

Я ищу в Интернете и не знаете, как идти от среза к массиву (без копирования) , Я всегда могу сделать Magic []byte (или даже uint64), но мне было любопытно, как мне перейти от типа []byte к [4]byte, если нужно?

+1

Прошла недавняя дискуссия о том, разрешено ли разрезать на массив. Результаты неубедительны, что-то вроде того, что вы хотите, может быть добавлено в будущем. Имейте в виду, что [4] байт - это объект, а не указатель на объект. Единственное, что может быть возможно, - назначить указателю на массив. – fuz

+0

https://play.golang.org/p/ulk0kmJzf6 –

ответ

27

Встроенный метод копирования будет только скопировать ломтик ломтик НЕ ломтик в массив.

Вы должны обмануть копию думая массив является ломтик

copy(varLead.Magic[:], someSlice[0:4]) 

Или использовать для цикла, чтобы сделать копию:

for index, b := range someSlice { 

    varLead.Magic[index] = b 

} 

Или, как Зупа сделал с помощью литералов. Я добавил их рабочий пример.

Go Playground

+1

Выполнение [0: 3] будет копировать только первые 3 элемента, а не все четыре. как и было предложено, do [0: 4] – galaktor

+1

Вы также можете использовать 'copy (varLead.Magic [:], someSlice [:])'. Это скопирует все содержимое, которое вписывается в массив. – Pascal

+2

Ну, просто 'copy (varLead.Magic [:], someSlice)' достаточно, так как он копирует только содержимое, соответствующее размеру массива. – shebaw

10

Вы выделили четыре байта внутри этой структуры и хотите присвоить значение этой четырехбайтовой секции. Нет концептуального способа сделать это без копирования.

Посмотрите на copy встроенный способ для этого.

6

Попробуйте это:

copy(lead.Magic[:], buf[0:4]) 
-4

Не. Сам срез достаточно для всех целей. Массив в go lang следует рассматривать как основную структуру среза. В каждом отдельном случае используйте только срез. Вам не нужно массировать себя. Вы просто делаете все по синтаксису среза. Массив предназначен только для компьютера. В большинстве случаев срез лучше, ясный в коде. Даже в других случаях до сих пор достаточно среза, чтобы отразить вашу идею.

+1

В * общих * срезах могут быть предпочтительнее массивы, но есть места, где массивы подходят и превосходят.Говорить «В каждом отдельном случае использовать только срез» неверно. –

+2

Пример того, где нужны массивы: как элемент структуры, который должен быть сопоставим (например, для использования его в качестве ключа карты). –

0

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

lead := Lead{} 

// make a reader to dispense bytes so you don't have to keep track of where you are in buffer 
reader := bytes.NewReader(buffer) 

// read into each field in Lead, so Magic becomes buffer[0:4], 
// Major becomes buffer[5], Minor is buffer[6], and so on... 
binary.Read(reader, binary.LittleEndian, &lead) 
Смежные вопросы