请在GoLang中解释&和*指针

zer*_*ool 21 pointers go

我最近开始学习GoLang.当我尝试在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
    }
}
Run Code Online (Sandbox Code Playgroud)

wue*_*ueb 44

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

如果您像这样创建了User实例:u:= new(User)它将是一个指针,因为新函数返回一个指针.您还可以创建一个指向用户的指针,如下所示:var u*User.如果您执行了其中任何一项操作,则必须取消对Decode的调用中的&才能使其正常工作.

指针基本上是包含地址的变量.当你把&放在变量前面时,它返回地址.*可以读作'重定向'.所以当你创建这样的指针时:

var x*int

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

其中y是一些int.因此,如果您要打印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!")
    }

}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!


use*_*210 9

我会引用一个聪明的家伙:

&变量名称前面用于检索存储此变量值的地址.该地址是指针要存储的内容.

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

*在指针类型变量前面用于检索存储在给定地址的值.在Go中,这称为解除引用.

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