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 中执行二进制时获取输入

MySQL 到 JSON 不一致提取

go - 在同一包中自己的文件中单独实现

go - 如何编写一个golang验证函数,让客户端能够优雅地处理?

go - 在 Go 中,如何重用 ReadCloser?

google-app-engine - 如何在 AppEngine 上的 Go 中包含第 3 方库?

unit-testing - 模拟代码减少代码覆盖率

pointers - 变量中的 slice 指针在追加期间更改行为

go - 我的系统服务有什么问题

go - go CLI解决方案最佳实践