go - 如何在golang中更改指针 slice

标签 go

我正在努力更好地理解围棋。我为自己创建了一个小练习:将指针 slice 传递给函数并对其进行修改。

这是我想出的:

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var data *[]byte
    fillData(data)
    fmt.Println((*data)[0:5])
}

func fillData(data *[]byte) {
    b := []byte("hello")
    fmt.Println(b[0:5])
    fmt.Println(string(b[0:5]))
    data = (*[]byte)(unsafe.Pointer(&b[0]))
}

但它给出了一个无效的内存地址或零指针取消引用错误。我知道我不会在实际代码中使用这样的东西,但我只是好奇如何传递 slice 并修改它而不返回它。

https://play.golang.org/p/_K5ltKKKNV

最佳答案

当您尝试更新 fillData 中的 data 时,您会犯两个错误。首先,您更新指针而不是它指向的内容。其次,data 是一个 nil 指针,因此通过该指针写入会导致 nil 指针错误。

这是编写代码的一种可能方法。 data 以零 slice 开始,并在 fillData 中更新。这会将 slice 信息(len、cap 和指向数组的指针)从 b 复制到 *data,这意味着 data 将与共享信息b(重要的是,包括共享底层数组)。

package main

import "fmt"

func main() {
    var data []byte
    fillData(&data)
    fmt.Println(data, data[0:5])
}

func fillData(data *[]byte) {
    b := []byte("hello")
    *data = b[0:1]
}

另一种方法是让 data 成为一个指针,并更新它。然后,您必须将双指针传递给 fillData。看起来像这样:

package main

import "fmt"

func main() {
    var data *[]byte
    fillData(&data)
    fmt.Println((*data)[0:5])
}

func fillData(data **[]byte) {
    b := []byte("hello")
    *data = &b
}

最后,编写此代码的最佳方式是根本不使用指针,而只返回 slice 。与 C 或 C++ 不同,它很少需要对函数使用“输出”参数。那是因为 go 允许多个返回值。

package main

import "fmt"

func main() {
    data := getData()
    fmt.Println(data, data[0:5])
}

func getData() []byte {
    return []byte("hello")[:1]
}

关于go - 如何在golang中更改指针 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29335766/

相关文章:

go - 如何在 Go 中自动将数据传递给模板?

python - Golang 和 SPI - 尝试初始化 RF522 驱动器

reflection - 区分同一包中具有相同名称的结构

javascript - Golang 中的 JSON.stringify 等价于 map[string]interface{}

go - 在 chromedp.ActionFunc 中赋值的变量不能被 SendKeys 输入

go - 找不到包数学/位

docker - 在 Docker 中从 Github 运行 go 文件

Golang : Use one value in conditional from function returning multiple arguments

go - 使用golang注释生成Swagger规范

go - 如何从其他包中调用Golang中的方法