2015-12-09 94 views
-1

我收到错误:undefined:请求在编译期间。我明白为什么我得到错误,但我不知道如何克服它。这是我的代码:转到未定义变量

switch path { 
case "user.save": 
    var req SaveRequest 
case "user.update": 
    var req UpdateRequest 
} 

err := c.BindJSON(&req) 
if err != nil { 
    c.JSON(http.StatusOK, gin.H{"error_code": "SERVER_ERROR", "message": "Request is not valid JSON"}) 
    return 
} 

c.Set("req", req) 

我想解析JSON请求,然后将它们添加到上下文中。我重申,如果我在switch声明之前定义我的req变量,那么这应该可以解决问题,但我不知道最初声明的是哪种类型?

回答

4

围棋是lexically scoped using blocks。这意味着req的声明仅在其代码块case块中可见。

您需要在相同的作用域或外部作用域中声明req,您希望从中使用它。

var req interface{} 
switch path { 
case "user.save": 
    req = &SaveRequest{} 
case "user.update": 
    req = &UpdateRequest{} 
} 

err := c.BindJSON(req) 
+0

谢谢 - 是的,我了解范围。我只是不确定如何在这种情况下最好地构建代码! – tommyd456

+0

@ tommyd456:如果您希望'req'可能有多种类型,您需要使用'interface {}'(或者更具体的通用接口,如果有的话) – JimB

+0

谢谢 - 我不知道如何使用'interface {}'那样。 – tommyd456

2

这是因为你在switch语句中声明它。不能保证在err := c.BindJSON(&req)行执行时已定义其中的任一个。根据外界对输入的理解,你可能知道这不会发生,但编译器不能。您在每个case语句中声明的变量都是针对该语句的范围。

你只需要做一点重构。您可以将此err := c.BindJSON(&req)转入案例声明。你可以使用一个接口来更普遍地声明该变量,并在以后处理它的类型。做你认为最好的东西。很可能您在其他语言中遇到过这种类型相似的系统(例如,在C,C++,C#和Java中也是如此)。

+1

这不,这是不允许的,或者既不路径可能被执行,那么它仅仅是走的是使用块(没有什么关系的类型系统要么) – JimB

+0

@JimB词法范围好点,那是措辞不佳。你知道我的意思,但在技术上是错误的。也许我会编辑,也许你的评论是足够的。 – evanmcdonnal

2

将您BindJSON逻辑到switch声明:

var err error 
switch path { 
case "user.save": 
    var req SaveRequest 
    err = c.BindJSON(&req) 
case "user.update": 
    var req UpdateRequest 
    err = c.BindJSON(&req) 
} 

if err != nil { 
    c.JSON(http.StatusOK, gin.H{"error_code": "SERVER_ERROR", "message": "Request is not valid JSON"}) 
    return 
} 
+0

感谢你们 - 我忘了说我还打电话给'req',所以我仍然会留下相同的错误。你能稍微修改你的答案吗?我更新了我的代码示例。 – tommyd456