28

Is there convenient way for initial a byte array?

package main
import "fmt"
type T1 struct {
  f1 [5]byte  // I use fixed size here for file format or network packet format.
  f2 int32
}
func main() {
  t := T1{"abcde", 3}
  // t:= T1{[5]byte{'a','b','c','d','e'}, 3} // work, but ugly
  fmt.Println(t)
}

prog.go:8: cannot use "abcde" (type string) as type [5]uint8 in field value

if I change the line to t := T1{[5]byte("abcde"), 3}

prog.go:8: cannot convert "abcde" (type string) to type [5]uint8

Daniel YC Lin
  • 15,050
  • 18
  • 63
  • 96
  • This is similar to: http://stackoverflow.com/questions/8032170/how-to-assign-string-to-bytes-array. – jimt Nov 07 '11 at 16:36

2 Answers2

25

You could copy the string into a slice of the byte array:

package main
import "fmt"
type T1 struct {
  f1 [5]byte
  f2 int
}
func main() {
  t := T1{f2: 3}
  copy(t.f1[:], "abcde")
  fmt.Println(t)
}

Edit: using named form of T1 literal, by jimt's suggestion.

SteveMcQwark
  • 2,169
  • 16
  • 9
  • In this method, the copy work will delayed on runtime instead of compile time. Am I right? – Daniel YC Lin Nov 08 '11 at 06:08
  • @DanielYCLin:That is correct. The example shown here can also do without the `[5]byte{}` bit in the struct initializer. A fixed array struct field is already initialized. There is no need to do it twice: `t := T1{f2: 3}; copy(t.f1[:], "abcde")`. – jimt Nov 08 '11 at 10:53
  • The copy can't happen at compile time in either case. In both cases, data will be copied onto the stack or into the heap from the program data. Also, while I would agree that the named form is nicer (I was considering using it, but decided not to), the array does not get initialized twice in the code I posted. – SteveMcQwark Nov 09 '11 at 05:14
  • I think the fancy usage to assign "abcde" directly into [5]byte may NOT be modified by Go authors. So, this solution is only method. – Daniel YC Lin Nov 10 '11 at 05:07
  • +1 it should be noted that copy does not panic if the string is longer or shorter than the sized byte array. hence, no error checking needed in production. – eduncan911 Feb 22 '15 at 15:21
  • Is there a new and better solution to this now? – majidarif Feb 27 '15 at 07:32
  • No. There's still no way to convert a string literal to an array. However, there's nothing really wrong with doing the copy. – SteveMcQwark Apr 04 '15 at 02:40
8

Is there any particular reason you need a byte array? In Go you will be better off using a byte slice instead.

package main
import "fmt"

type T1 struct {
   f1 []byte
   f2 int
}

func main() {
  t := T1{[]byte("abcde"), 3}
  fmt.Println(t)
}
jimt
  • 25,324
  • 8
  • 70
  • 60