gpt4 book ai didi

go - 如何将 []byte 转换为 [8]uint8

转载 作者:IT王子 更新时间:2023-10-29 01:53:50 25 4
gpt4 key购买 nike

我需要填充一个具有 [8]uint8 类型成员的结构体.这需要填充类型为 []byte 的字节数组。初始化为长度 8。 简单的方法不起作用:

Data:   [8]uint8(RequestFrame(0x180, r)),


cannot convert .. (type []byte) to type [8]uint8

由于两个数组在结构上是相同的,如果这可以通过强制转换/赋值而不是复制来完成会更好吗?

最佳答案

背景
您的“简单方法”的问题在于 slice
(任何类型)是 struct -typed 由一个指针组成
和两个整数;指针包含地址
底层(支持)数据数组,整数包含
什么len()cap()内置函数返回该 slice 。
换句话说, slice 是数组的 View 。
然后,在 Go 中,没有类型转换的概念;只有
类型转换,这些转换可能只发生在
具有相同底层表示的类型¹。
由于 slice 和数组可能没有相同的底层
表示(数组实际上是一个连续的内存块
大小刚好足以包含数组的所有元素),
您所谓的类型转换可能不合法。
可能的解决方案
有两种可能的解决方案。
最简单的方法是从 slice 的数据中复制数据
将数组支持到新分配的数组中:

var (
src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
dst [8]uint8
)
copy(dst[:], src[:8])
请注意, slice 和
数组类型:数组类型对其元素的类型进行编码
以及它的长度(即长度是类型的一部分),
而 slice 类型只对其元素的类型进行编码
(并且在运行时可以是任意长度)。
这意味着您可能需要在此之前进行检查
复制以确保源 slice 正好有 8 个
元素,即 len(src) == len(dst) .
这个不变量可能由其他一些代码强制执行,但我认为
我会提前警告你:如果 src少于 8
元素, src[:8]表达式会在运行时 panic ,
如果它包含更多,那么问题是
只复制其中的前 8 个正是所需要的。
第二种方法(诚然更困惑)是重新使用
slice 的底层数组:
import "unsafe"

var (
src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
dstPtr *[8]uint8
)

if len(src) != len(*dstPtr) {
panic("boom")
}
dstPtr = (*[8]uint8)(unsafe.Pointer(&src[0]))
在这里,我们刚刚获取了第一个元素的地址
包含在 slice 的底层数组中并执行
一个“脏”的两阶段类型转换,使获得的
指针类型为 *[8]uint8 ——也就是说,“一个地址
8 个数组 uint8 s”。
注意两点:
  • 结果指针现在指向
    与原始 slice 相同的内存块。
    这意味着现在可以通过
    slice 和我们得到的指针。
  • 一旦您决定分配数组的数据
    [8]uint8 类型的变量(并将其作为参数传递
    到该类型的函数参数),您将取消引用
    那个指针(就像 *dstPtr ),在那一刻
    数组的数据将为 复制的。
    我特别提到这一点,因为人们经常求助
    像这样的黑客将后备阵列拉出
    一个 slice 正是为了不复制内存。

  • TL; 博士
    复制数据(在据称验证了 len(src) == len(dst)不变持有)。
    复制 8 个字节很快(在典型的 64 位 CPU 上,这将是
    MOV指令,或最多两个),代码将
    直截了当。
    只有当你真的
    需要在一些关键的热路径上进行优化。
    在这种情况下,请广泛评论解决方案并注意
    不会意外取消引用您的指针。

    ¹ 此规则有明显的异常(exception):
  • A []byte可转换为 string ,反之亦然。
  • A string可转换为 []rune ,反之亦然。
  • int可转换为 string (但自 Go 1.15 go vet gives a warning about it 起,此功能将来可能会被禁止)。
  • 关于go - 如何将 []byte 转换为 [8]uint8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52609566/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com