如果我在if块内创建变量,则以后将无法使用它。如果我在if块之前创建一个变量,而if块的计算结果为false,则会出现“变量已创建且未使用”的错误。
我敢肯定,这是设计使然,我正在尝试做我不应该做的事情,但是我想做的事情背后的逻辑对我来说很有意义。如果url中有页面信息,我以后想在sql语句中使用它,但是如果url中没有页面信息,则不需要这些变量。
http://pastebin.com/QqwpdM1d
编辑:这是代码:
var pageID string var offset int if len(r.URL.Path) > len("/page/") { pageID := r.URL.Path[len("/page/"):] offset, err := strconv.Atoi(pageID) if err != nil { log.Fatal(err) } } conn := "..." db, err := sql.Open("mysql", conn) defer db.Close() if err != nil { log.Fatal(err) } var rows *sql.Rows if offset != 0 { // ... }
如果您在if语句之前声明一个变量并在if块中使用它,则条件求值并不重要,这不是编译时错误。
if
这种情况下的错误是您没有在if块内使用声明的变量。您的代码:
var pageID string var offset int if len(r.URL.Path) > len("/page/") { pageID := r.URL.Path[len("/page/"):] offset, err := strconv.Atoi(pageID) if err != nil { log.Fatal(err) } }
在内部,if您没有分配给先前声明的pageID,而是使用了简短的变量声明 :=,该声明创建了一个新变量,遮盖了在外部块中创建的变量,并且该变量仅在if块的末尾有效(其作用域在最里面的包含块的末尾)。
pageID
:=
解决方案是(您最可能想要的)简单地使用赋值=(将值赋给现有变量):
=
pageID = r.URL.Path[len("/page/"):]
为了使其理解,请参见以下示例:
i := 1 fmt.Println("Outer:", i) { i := 2 // Short var decl: creates a new i, shadowing the outer fmt.Println("Inner:", i) } fmt.Println("Outer again:", i)
输出(在Go Playground上尝试):
Outer: 1 Inner: 2 Outer again: 1