我是Go的新手,正在尝试编写一个读取RPM文件的应用程序。 每个块的开头都有[4]byte的魔术字符。

这是我的结构

1
2
3
4
5
6
7
8
9
type Lead struct {
  Magic        [4]byte
  Major, Minor byte
  Type         uint16
  Arch         uint16
  Name         string
  OS           uint16
  SigType      uint16
}

我正在尝试执行以下操作:

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

我在网上搜索,不确定如何从切片到数组(不进行复制)。 我总是可以制作魔术[]byte(甚至是uint64),但是我对如何从类型[]byte转换为[4]byte感到好奇。

  • 最近有关于是否应允许将其切成阵列的争论。 结果没有定论,将来可能会添加类似您想要的内容。 请记住,[4] byte是一个对象,而不是指向该对象的指针。 唯一可能的是分配一个指向数组的指针。
  • play.golang.org/p/ulk0kmJzf6

内置方法copy只会将一个切片复制到一个切片,而不是将切片复制到一个数组。

您必须欺骗复制以将数组视为切片

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

或使用for循环进行复制:

1
2
3
4
5
for index, b := range someSlice {

    varLead.Magic[index] = b

}

或者像zupa所做的那样使用文字。我已添加到他们的工作示例中。

去游乐场

  • [0:3]仅会复制前三个元素,而不是全部四个。 否则建议执行[0:4]
  • 您也可以使用copy(varLead.Magic[:], someSlice[:])。 这将复制适合数组的所有内容。
  • 好吧,只要copy(varLead.Magic[:], someSlice)就足够了,因为它只会复制适合数组的内容。

您已在该结构中分配了四个字节,并想为该四个字节部分分配一个值。没有复制就没有概念上的方法。

查看内置的copy,了解如何执行此操作。

试试这个:

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

您可能只需阅读一次即可完成整个操作,而不必逐一阅读每个字段。如果字段是固定长度的,则可以执行以下操作:

1
2
3
4
5
6
7
8
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)

别。切片本身足以满足所有目的。 go lang中的数组应被视为slice的基础结构。在每种情况下,仅使用切片。您不必整理自己。您只需按片语法即可完成所有操作。阵列仅适用于计算机。在大多数情况下,切片更好,代码清晰。即使在其他情况下,切片仍然足以反映您的想法。

  • 通常,切片比阵列更可取,但是在某些地方,阵列是合适且优越的。 说"在每种情况下,仅使用切片"是错误的。
  • 数组在何处是必要的示例:作为必须可比较的结构的成员(例如,将其用作映射键)。
  • 我使用数组表示语义,是说下面的代码不会追加到该结构中。 同样为了性能,为什么不呢。