当我试图将变量作为参数传递到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
    }
}

推荐答案

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

如果像这样创建User实例:u:=new(User),它将是一个指针,因为新函数返回一个指针.您还可以创建一个指向如下用户的指针:var u*user.如果你做了这两件事中的任何一件,你就必须拿出通话中的&来解码它才能工作.

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

变量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!")
    }

}

希望这能有所帮助!

Go相关问答推荐

golang 的通用 map 功能

正在使用terratest执行terraform脚本测试,但遇到错误退出状态1

如何防止程序B存档/删除围棋中程序A当前打开的文件?

当我有外键时,如何使用 GORM 创建数据库的新条目

仅使用公共 api 对 alexedwards/scs 进行简单测试

如何将Golang测试用例的测试覆盖率值与特定阈值进行比较

golang gin 获取 cookie json

如何将整数哈希细分为范围

如果值为 false,gRPC 不返回布尔值

有没有办法约束(通用)类型参数?

assert: mock: I don't know what to return because the method call was unexpected 在 Go 中编写单元测试时出错

golang pic.ShowImage 为什么它不生成图像而是向我发送base64值

我如何解码 aes-256-cfb

分配空切片而不引用其类型?

正确编码 JWT

如何在测试中传递用户名和密码等参数

正则表达式处理数字签名的多个条目

如何断言类型是指向golang中接口的指针

如何发送带有登录数据的 GET 请求并将 cookie 数据保存到 txt 文件?

并发 map map导致的 Golang 数据竞争