Pointers 使用指向值的指针作为切片
是否可以将指向特定值的指针转换为切片 例如,我想将单个字节从Pointers 使用指向值的指针作为切片,pointers,go,slice,Pointers,Go,Slice,是否可以将指向特定值的指针转换为切片 例如,我想将单个字节从io.Reader读入uint8变量io.Reader.Read接受一个切片作为它的参数,所以我不能像在C中那样简单地为它提供一个指向变量的指针 我认为从指针创建长度为1、容量为1的片是安全的操作。显然,它应该与从长度为1的数组创建切片相同,这是允许的操作。有没有一种简单的方法可以用普通变量实现这一点?或者可能我不理解某些东西,这是被禁止的原因?切片不仅是指针,就像C中的数组一样。它还包含数据的长度和容量,如下所示: struct {
io.Reader
读入uint8
变量io.Reader.Read
接受一个切片作为它的参数,所以我不能像在C中那样简单地为它提供一个指向变量的指针
我认为从指针创建长度为1、容量为1的片是安全的操作。显然,它应该与从长度为1的数组创建切片相同,这是允许的操作。有没有一种简单的方法可以用普通变量实现这一点?或者可能我不理解某些东西,这是被禁止的原因?切片不仅是指针,就像C中的数组一样。它还包含数据的长度和容量,如下所示:
struct {
ptr *uint8
len int
cap int
}
因此,是的,您需要创建一个切片。创建var a uint8的切片的最简单方法是[]uint8{a}
a := uint8(42)
fmt.Printf("%#v\n", []uint8{a})
(但在重新阅读您的问题后,这并不是一个解决方案)
但是,如果希望从变量创建指向相同内存空间的切片,可以使用unsafe
包。这很可能会被劝阻
fmt.Printf("%#v\n", (*[1]uint8)(unsafe.Pointer(&a))[:] )
切片不仅是指针,就像C中的数组一样。它还包含数据的长度和容量,如下所示:
struct {
ptr *uint8
len int
cap int
}
因此,是的,您需要创建一个切片。创建var a uint8的切片的最简单方法是[]uint8{a}
a := uint8(42)
fmt.Printf("%#v\n", []uint8{a})
(但在重新阅读您的问题后,这并不是一个解决方案)
但是,如果希望从变量创建指向相同内存空间的切片,可以使用unsafe
包。这很可能会被劝阻
fmt.Printf("%#v\n", (*[1]uint8)(unsafe.Pointer(&a))[:] )
与其让这个琐碎的任务(过度)复杂化,为什么不使用简单的解决方案呢?即通过。读取长度为1的切片,然后将其第0个元素分配给变量。与其(过度)使这项琐碎的任务复杂化,为什么不使用简单的解决方案呢?即通过。读取长度为1的切片,然后将其第0个元素分配给变量。当我想向io.Reader提供变量时,我找到了一种克服这种情况的方法。去标准图书馆太棒了
import (
"io"
"encoding/binary"
)
...
var x uint8
binary.Read(reader, LittleEndian, &x)
作为一种副作用,这适用于任何基本类型,甚至适用于某些非基本类型。当我想向io.Reader
提供变量时,我找到了一种克服这种情况的方法。去标准图书馆太棒了
import (
"io"
"encoding/binary"
)
...
var x uint8
binary.Read(reader, LittleEndian, &x)
作为一种副作用,这适用于任何基本类型,甚至适用于某些非基本类型。是的,我想使用切片来提供对变量的访问。因此,不使用不安全的方法是不可能做到这一点的。Go不允许在uint8和[1]uint8之间进行转换(我觉得这很安全)。因此,据我所知,不安全
是唯一的方法。如果我错了,我自己也很好奇一个更好的解决方案。我的答案是直接的问题:“可能吗…”,是的,是的。但实际上,我还建议使用jnml的解决方案。是的,我想使用一个切片来提供对变量的访问。因此,不使用不安全的方法是不可能做到这一点的。Go不允许在uint8和[1]uint8之间进行转换(我觉得这很安全)。因此,据我所知,不安全
是唯一的方法。如果我错了,我自己也很好奇一个更好的解决方案。我的答案是直接的问题:“可能吗…”,是的,是的。但实际上,我也建议使用jnml的解决方案。这就是我现在正在做的。我只是想知道,在不定义切片变量的情况下,是否有更好看的解决方案。也许可以使用[1]uint8数组而不是uint8变量。然后它会适合io.Reader。这就是我现在正在做的。我只是想知道,在不定义切片变量的情况下,是否有更好看的解决方案。也许可以使用[1]uint8数组而不是uint8变量。然后它将适合io.Reader。很好的发现!Go开发人员确实为我们创建了一组非常有用的包。您是否意识到您(间接地)正在使用pass-byinterface{}
、反射和类型断言?这是一种寻找最慢的方法的竞争吗?这种方法可以避免大约2条CPU指令可能用于一个简单的赋值?是的,我知道这里使用接口间接寻址。我现在并不是在追求性能,而是在寻找惯用的解决方案,在这个过程中发现了不同的东西。这就是我发现的,我只是希望它能对某些人有用。很好的发现!Go开发人员确实为我们创建了一组非常有用的包。您是否意识到您(间接地)正在使用pass-byinterface{}
、反射和类型断言?这是一种寻找最慢的方法的竞争吗?这种方法可以避免大约2条CPU指令可能用于一个简单的赋值?是的,我知道这里使用接口间接寻址。我现在并不是在追求性能,而是在寻找惯用的解决方案,在这个过程中发现了不同的东西。这就是我发现的,我只是希望它能对某些人有用。