【问题标题】:Reassigning a pointer func parameter重新分配指针函数参数
【发布时间】:2019-06-12 17:57:10
【问题描述】:

我正在尝试重新分配一个指向作为 func 参数传递的新值的指针,但是一旦我退出该函数,该指针再次具有 nil 值。

我已经单步执行了代码,它似乎可以正常工作,直到我退出函数进入调用函数,其中传递的指针仍然持有 NIL 值。

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

我希望以下工作:

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

我对 GO 还很陌生,所以我相信我在这里没有掌握一个概念。任何帮助将不胜感激。

【问题讨论】:

    标签: function pointers go


    【解决方案1】:

    参数在函数中充当局部变量。您可以更改它们的值,但这只会更改局部变量的值。它们独立于您传递其值的变量。

    如果你想修改某个东西,你必须传递它的地址,并修改指向的值,例如:

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

    输出(在Go Playground 上试用):

    before 0
    after 2
    

    同样的事情也适用于指针变量:如果你想修改一个指针变量,你必须再次传递它的地址,并修改指向的值。如果是指针,类型将是指向指针的指针,例如:

    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
    }
    

    输出(在Go Playground上试试):

    before 0x416020 0
    after 0x416040 2
    

    当然,如果你有一个指针变量,不想只修改指针的值,你可以只传递指针,修改指针的值:

    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
    }
    

    输出(在Go Playground上试试):

    before 0x416020 0
    after 0x416020 2
    

    需要注意的一点:您不能将nil 指针传递给函数并期望能够将任何内容分配给指向的值:nil 指针指向无处。您必须传递一个非nil 指针,或者您可以返回指针值(并在调用者处分配它)。

    【讨论】:

    • 感谢您澄清这一点,我认为指针会自动通过引用传递。我现在正在尝试使用*stmt = *res,但我得到了一个错误的内存地址,但我认为这个错误应该在其他地方寻找?
    • @P.Winz 我认为是这样。但我什至不知道你用的是哪个包。
    • 主要是github.com/jmoiron/sqlx。我不太明白的是:我将一个空的sqlx.Stmt 指针传递给这个函数。我希望填充指针而不是实际创建一个新指针。 db.PreparexStatement() 将返回另一个 sqlx.Stmt 指针,所以我应该能够像这样设置值 *stmt = res ,对吧?我检查了PreparexStatement 函数的结果,它似乎返回了一个非常好的指针,指向一个非常好的结构。
    • @P.Winz 您不能传递nil 指针并期望将任何内容分配给指向的值:nil 指针指向任何地方。为了能够在函数内部设置指向的值,您必须传递一个非nil 指针。或者你必须返回指针。
    • 我只是在做一些研究时才意识到这一点。感谢您的快速帮助,我想我现在掌握了这个概念:)
    猜你喜欢
    • 1970-01-01
    • 2018-08-24
    • 2019-10-19
    • 2019-04-30
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多