在Go语言中将字符串转换为固定大小的字节数组

28
有没有方便的方法来初始化一个字节数组?
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:不能将字符串"abcde"(类型为string)用作字段值中的[5]uint8类型

如果我将该行更改为t := T1{[5]byte("abcde"), 3}

prog.go:8:无法将字符串"abcde"(类型为string)转换为[5]uint8类型


这类似于:https://dev59.com/DWsz5IYBdhLWcg3wOlWh。 - jimt
2个回答

25

您可以将该字符串复制到字节数组的切片中:

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)
}

编辑:使用Jimt的建议,使用T1文字的命名形式。


在这种方法中,复制工作将延迟到运行时而不是编译时。我说得对吗? - Daniel YC Lin
@DanielYCLin:没错。这里展示的例子也可以在结构体初始化器中省略[5]byte{}。一个固定长度的数组结构体字段已经被初始化了,没有必要重复做一遍:t := T1{f2: 3}; copy(t.f1[:], "abcde") - jimt
无论哪种情况,复制都不能在编译时发生。在两种情况下,数据将从程序数据复制到堆栈或堆中。此外,虽然我同意命名形式更好(我考虑使用它,但最终决定不使用),但在我发布的代码中,数组并没有被初始化两次。 - SteveMcQwark
需要注意的是,如果字符串比指定大小的字节数组长或短,复制操作不会引发 panic。因此,在生产环境中不需要进行错误检查。 - eduncan911
现在是否有一种新的更好的解决方案? - majidarif
显示剩余2条评论

8

你需要使用字节数组有特殊的原因吗?在Go语言中,你最好使用字节片(byte slice)代替。

package main
import "fmt"

type T1 struct {
   f1 []byte
   f2 int
}

func main() {
  t := T1{[]byte("abcde"), 3}
  fmt.Println(t)
}

4
我需要一个字节数组来进行网络数据包传输,并将我的数据保存到文件中。 - Daniel YC Lin
2
如果你想这样做,你也应该使用固定大小的整数(int32、int64)。 - SteveMcQwark
这应该是最好的答案。 - JayD3e
5
这不是正确的答案,因为我需要一个固定长度的字节数组而不是一个字节切片。 - Daniel YC Lin
这并没有真正回答问题;有时固定长度的数组是必要的。我又得去别处寻找答案了。 - user1974458

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接