当前位置: 首页 > 面试题库 >

在不同类型的切片之间转换

仉磊
2023-03-14
问题内容

[]byte从UDP套接字获取了一个字节片(),并希望将其视为整数片([]int32),而无需更改基础数组,反之亦然。在C(++)中,我只是在指针类型之间进行转换;我将如何在Go中执行此操作?


问题答案:

正如其他人所说,在Go中强制转换指针被认为是错误的形式。这是正确的Go方式示例以及与C数组转换等效的示例。

警告:所有代码未经测试。

在此示例中,我们使用encoding/binary包将每组4个字节转换为int32。这样更好,因为我们指定了字节序。我们也没有使用unsafe包破坏类型系统。

import "encoding/binary"

const SIZEOF_INT32 = 4 // bytes

data := make([]int32, len(raw)/SIZEOF_INT32)
for i := range data {
    // assuming little endian
    data[i] = int32(binary.LittleEndian.Uint32(raw[i*SIZEOF_INT32:(i+1)*SIZEOF_INT32]))
}

错误的方式(C数组转换)

在此示例中,我们告诉Go忽略类型系统。这不是一个好主意,因为它可能会在Go的另一个实现中失败。它假定的事情不在语言规范中。但是,此版本不做完整副本。此代码使用不安全的方式访问所有切片中常见的“
SliceHeader”。标头包含指向数据(C数组),长度和容量的指针。首先,我们需要更改长度和容量,而不仅仅是将标头转换为新的slice类型,因为如果将字节视为新类型,则元素数量会减少。

import (
    "reflect"
    "unsafe"
)

const SIZEOF_INT32 = 4 // bytes

// Get the slice header
header := *(*reflect.SliceHeader)(unsafe.Pointer(&raw))

// The length and capacity of the slice are different.
header.Len /= SIZEOF_INT32
header.Cap /= SIZEOF_INT32

// Convert slice header to an []int32
data := *(*[]int32)(unsafe.Pointer(&header))


 类似资料:
  • 问题内容: 我在以下测试代码中尝试转换为a 时并没有完全理解问题所在: 与有所不同 吗? 还是ListSociete与ListSociete不同? 谢谢。 问题答案: 您当前正在处理两种不同的类型: 和匿名的: 如果不是标记,那么这两个将是相同的。在 围棋规格 的状态(我的重点): 如果两个struct类型具有相同的字段序列,并且对应的字段具有相同的名称,相同的类型 和相同的tag ,则它们是 相

  • 我偶然发现了这种并发症,花了4个多小时调试和谷歌搜索,但无济于事... 基本上我这里有1个JFrame,2个JPanel。我将JFrame设置为JPanel的第1个内容窗格,当我运行应用程序时,JFrame将显示,其中包含JPanel。 现在这个JPanel里面有1个JButton,当我点击它时,我希望它切换到另一个JPanel。正如您从代码中看到的,当我单击JButton(AddProduct)

  • 我试图在java中实现不同类型之间的转换器:我有一个超级类foo,有2个子类: fo1和fo2,我也有2个不相关的其他类bar1和bar2,我试图实现一个转换器从bar1到fo1和bar2to fo2(与之相反)。 因为我在这里有继承,所以我想应该创建一个泛型类型的接口(将是bar1或bar2),它将定义转换所需的函数,我还想让转换器成为bar1和bar2的通用转换器,我认为它应该以某种方式使用接

  • 我是android开发的新手,请多多包涵。我有三个片段-Frag1、Frag2和frag3。Frag1是一种ListView,有一个项目列表,该列表是在应用程序启动时创建的。Frag2和Frag3基本上对应于视频视图,它将用于从不同的播放器播放不同的视频。其中一个将播放内容视频,另一个将播放广告视频。 当我点击Frag1中的一个特定项时,我希望同时创建Frag2和frag3。我想有两个片段,因为我

  • String转换到Byte数组时,每个byte(byte类型其实就是uint8)保存字符串对应字节的数值。 注意Go的字符串是UTF-8编码的,每个字符长度是不确定的,一些字符可能是1、2、3或者4个字节结尾。 示例1: package main import "fmt" func main() { s1 := "abcd" b1 := []byte(s1) fmt.Pri

  • 问题内容: 我目前正在努力完成出色的“围棋之旅”。我使用以下解决方案完成了其中一项练习(#45): 我不明白为什么我必须使用两次该类型的语句(请参见摘要中的注释)。这似乎是多余的,但我不知道该怎么做。 问题答案: Go中没有其他方法可以做到这一点。 是的,我同意这很冗长,但有必要。第二个make()语句完全独立于第一个。可以争论的是,编译器应该能够从推断类型,但此时还不行。 另一点:如果在第二种情