为了账号安全,请及时绑定邮箱和手机立即绑定

请解释 &, 和 * 指针

请解释 &, 和 * 指针

Go
慕斯709654 2021-11-08 19:15:54
当我尝试在 Go 函数中将变量作为参数传递时,编译器在多个实例中抛出错误。有时我已经能够通过在变量前面使用指针来调试它。& 和 * 指针似乎都清除了错误。不过,我想知道为什么。我想知道 & 和 * 之间的区别是什么,以及何时应该使用它们。谢谢!func (ctx *NewContext) SendNotification(rw http.ResponseWriter, req *http.Request, p httprouter.Params) {    decoder := json.NewDecoder(req.Body)    var u User    if err := decoder.Decode(&u); err != nil {        http.Error(rw, "could not decode request", http.StatusBadRequest)        return    }}
查看完整描述

3 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

在上面的示例中,您将 u 定义为 User 类型,但不是指向 User 的指针。所以你需要 &u 是因为 json 包中的 Decode 函数需要一个地址或指针。


如果您像这样创建 User 的实例: u := new(User) 它将是一个指针,因为 new 函数返回一个指针。你也可以像这样创建一个指向用户的指针:var u *User。如果您执行了其中任何一项操作,则必须&在对 Decode 的调用中删除才能使其工作。


指针基本上是保存地址的变量。当您将 & 放在变量前面时,它会返回地址。* 可以读作'redirect of'。因此,当您创建这样的指针时:


var x *int


这可以理解为 x 将重定向到一个 int。当你给 x 赋值时,你会给它一个这样的地址: y := 10 x = &y


其中 y 是一些整数。因此,如果您要打印 x,您将获得 y 的地址,但是如果您打印 *x,您将重定向到 x 指向的 y 值是 10。如果您要打印 &x,您将获得指针 x 本身的地址。


如果你试图打印出 *y,它只是一个 int,而不是一个指针,它会抛出一个错误,因为你将使用一些不是要重定向到的地址的值进行重定向。


运行下面的一些指针乐趣:


package main


import "fmt"


func main() {

    var y int

    var pointerToY *int

    var pointerToPointerToInt **int


    y = 10

    pointerToY = &y

    pointerToPointerToInt = &pointerToY


    fmt.Println("y: ", y)

    fmt.Println("pointerToY: ", pointerToY)

    fmt.Println("pointerToPointerToInt: ", pointerToPointerToInt)


    fmt.Println("&y: ", &y)     // address of y

    fmt.Println("&pointerToY: ", &pointerToY)// address of pointerToY

    fmt.Println("&pointerToPointerToInt: ", &pointerToPointerToInt) // address of pointerToPointerToInt


    // fmt.Println(*y) throws an error because 

    // you can't redirect without an address.. 

    // y only has int value of 10

    fmt.Println("*pointerToY: ", *pointerToY) // gives the value of y

    fmt.Println("*pointerToPointerToInt: ", *pointerToPointerToInt)     // gives the value of pointerToY which is the address of y


    fmt.Println("**pointerToPointerToInt: ", **pointerToPointerToInt)    // this gives 10, because we are redirecting twice to get y


    if pointerToY == *pointerToPointerToInt {

        fmt.Println("'pointerToY == *pointerToPointerToInt' are the same!")

    }


    if pointerToY == &y {

        fmt.Println("'pointerToY == &y' are the same!")

    }


    if &pointerToY == pointerToPointerToInt {

        fmt.Println("'&pointerToY == pointerToPointerToInt' are the same!")

    }


    if y == **pointerToPointerToInt {

        fmt.Println("'y == **pointerToPointerToInt' are the same!")

    }


    if pointerToY == *pointerToPointerToInt {

        fmt.Println("'pointerToY == *pointerToPointerToInt' are the same!")

    }


}

希望这可以帮助!


查看完整回答
反对 回复 2021-11-08
?
饮歌长啸

TA贡献1951条经验 获得超3个赞

我会引用一位聪明的家伙的话:

变量名前面的 & 用于检索该变量值的存储地址。该地址是指针将要存储的地址。

* 在类型名称之前,表示声明的变量将存储该类型的另一个变量的地址(不是该类型的值)。

* 在指针类型的变量前面用于检索存储在给定地址的值。在 Go 语言中,这称为取消引用。

来源:http : //piotrzurek.net/2013/09/20/pointers-in-go.html


查看完整回答
反对 回复 2021-11-08
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

显示代码执行顺序的简单示例。


   import (

        "fmt"

    )


    func main() {

        x := 0

        fmt.Println("Step 1", x)

        foo(&x)

        fmt.Println("Step 4", x)

    }


    func foo(y *int) {


        fmt.Println("Step 2", *y)

        *y = 100

        fmt.Println("Step 3", *y)

    }

/*

 Steps  Result

   1      0

   2      0

   3      100

   4      100

 */


查看完整回答
反对 回复 2021-11-08
  • 3 回答
  • 0 关注
  • 193 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信