我正在努力更好地理解围棋。我为自己创建了一个小练习:将指针 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 并修改它而不返回它。
最佳答案
当您尝试更新 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/