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-by
interface{}
、反射和类型断言?这是一种寻找最慢的方法的竞争吗?这种方法可以避免大约2条CPU指令可能用于一个简单的赋值?是的,我知道这里使用接口间接寻址。我现在并不是在追求性能,而是在寻找惯用的解决方案,在这个过程中发现了不同的东西。这就是我发现的,我只是希望它能对某些人有用。很好的发现!Go开发人员确实为我们创建了一组非常有用的包。您是否意识到您(间接地)正在使用pass-by
interface{}
、反射和类型断言?这是一种寻找最慢的方法的竞争吗?这种方法可以避免大约2条CPU指令可能用于一个简单的赋值?是的,我知道这里使用接口间接寻址。我现在并不是在追求性能,而是在寻找惯用的解决方案,在这个过程中发现了不同的东西。这就是我发现的,我只是希望它能对某些人有用。