在Golang中,如何将切片转换为数组

在Golang中,如何将切片转换为数组

问题描述:

I am new to Go and trying to write an application that reads RPM files. The start of each block has a Magic char of [4]byte.

Here is my struct

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

I am trying to do the following:

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

I am searching online and not sure how to go from a slice to an array (without copying). I can always make the Magic []byte (or even uint64), but I was more curious on how would I go from type []byte to [4]byte if needed to?

我是Go语言的新手,正在尝试编写一个读取RPM文件的应用程序。 每个块的开头都有一个 [4] byte code>的Magic char。 p>

这是我的结构 p>

  type Lead struct {
 Magic [4] byte 
 Major,Minor byte 
 Type uint16  
 Arch uint16 
名称字符串
操作系统uint16 
 SigType uint16 
} 
  code>  pre> 
 
 

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

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

我正在在线搜索,不确定如何 从切片到数组(不复制)。 我总是可以将Magic设置为 [] byte code>(甚至是 uint64 code>),但是我对如何从 [] byte code类型输入感到好奇 >到 [4] byte code>(如果需要)? p> div>

The built in method copy will only copy a slice to a slice NOT a slice to an array.

You must trick copy into thinking the array is a slice

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

Or use a for loop to do the copy:

for index, b := range someSlice {

    varLead.Magic[index] = b

}

Or do as zupa has done using literals. I have added onto their working example.

Go Playground

You have allocated four bytes inside that struct and want to assign a value to that four byte section. There is no conceptual way to do that without copying.

Look at the copy built-in for how to do that.

Try this:

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

Don't. Slice itself is suffice for all purpose. Array in go lang should be regarded as the underlying structure of slice. In every single case, use only slice. You don't have to array yourself. You just do everything by slice syntax. Array is only for computer. In most cases, slice is better, clear in code. Even in other cases, slice still is sufficient to reflex your idea.

You might be able to do the whole thing with one read, instead of reading individually into each field. If the fields are fixed-length, then you can do:

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)