douju1852 2015-03-29 22:37
浏览 248
已采纳

如何在golang中更改指针切片

I'm trying to get a better understanding of go. I created a little exercise for myself: pass a pointer slice to a function and modify it.

This is what I came up with:

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]))
}

But it gives an invalid memory address or nil pointer dereference error. I know I wouldn't use something like this in real code but I was just curious how to pass a slice and modify it without returning it.

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

  • 写回答

1条回答 默认 最新

  • douqiang5933 2015-03-30 03:48
    关注

    When you try to update data in fillData, you make two errors. First, you update the pointer rather than what it's pointed to. Second, data is a nil pointer, so writing through that pointer will cause a nil pointer error.

    Here's one possible way to write the code. data starts as a zero'ed slice, and gets updated inside fillData. This will copy the slice information (len, cap, and pointer to array) from b to *data which means that data will share information with b (importantly, including sharing the underlying array).

    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]
    }
    

    Another way would be to have data being a pointer, and updating it. Then you have to pass a double pointer into fillData. That would look like this:

    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
    }
    

    Finally, the best way to write this code isn't to use pointers at all, and just return the slice. Unlike C or C++, it's rarely needed to use "output" parameters to functions. That's because go allows multiple return values.

    package main
    
    import "fmt"
    
    func main() {
        data := getData()
        fmt.Println(data, data[0:5])
    }
    
    func getData() []byte {
        return []byte("hello")[:1]
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格