douyue7408 2019-01-18 12:56
浏览 37
已采纳

重新分配指针函数参数

I'm trying to reassign a pointer to a new value that's been passed on as func parameter, but once I step out of the function, the pointer has a nil value again.

I've stepped through the code and it seems to work until I step out of the function into the calling function where the passed on pointer still holds a NIL value.

func Prepare(db *sqlx.DB, stmt *sqlx.Stmt, query String) error {
    res,err := db.PreparexStatement(context.Background(), query)
    stmt = res
    return err
}

I would expect the following to work:

func Boot(db *sqlx.DB, stmt *sqlx.Stmt, query String) {
    err := Prepare(db, stmt, query)
    if err != nil {
        //handle
    }
}

I'm still fairly new to GO, so I believe I fail to grasp a concept here. Any help would be greatly appreciated.

  • 写回答

1条回答 默认 最新

  • duanjianxiu9400 2019-01-18 13:06
    关注

    Parameters act as local variables inside a function. You may change their values, but that only changes the values of the local variables. They are independent from the variables whose value you pass.

    If you want to modify something, you have to pass its address, and modify the pointed value, e.g.:

    func main() {
        var x int
        fmt.Println("before", x)
        set(&x)
        fmt.Println("after", x)
    }
    
    func set(i *int) {
        *i = 2
    }
    

    Outputs (try it on the Go Playground):

    before 0
    after 2
    

    The same thing applies to pointer variables: if you want to modify a pointer variable, you again have to pass its address, and modify the pointed value. In case of a pointer, the type will be a pointer to pointer, e.g.:

    func main() {
        var x *int
        x = new(int)
        fmt.Println("before", x, *x)
        set(&x)
        fmt.Println("after", x, *x)
    }
    
    func set(i **int) {
        p := new(int)
        *p = 2
        *i = p
    }
    

    Output (try it on the Go Playground):

    before 0x416020 0
    after 0x416040 2
    

    Of course if you have a pointer variable and don't want to modify the pointer value just the pointed value, you can just pass the pointer, and modify the pointed value:

    func main() {
        var x *int
        x = new(int)
        fmt.Println("before", x, *x)
        set(x)
        fmt.Println("after", x, *x)
    }
    
    func set(i *int) {
        *i = 2
    }
    

    Output (try it on the Go Playground):

    before 0x416020 0
    after 0x416020 2
    

    One thing to note: you can't pass a nil pointer to a function and expect to be able to assign anything to the pointed value: nil pointers point to nowhere. You have to pass a non-nil pointer, or as an alternative you may return the pointer value (and assign it at the caller).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题