Variables 如果条件为真,如何在go中创建变量?

Variables 如果条件为真,如何在go中创建变量?,variables,go,Variables,Go,如果我在If块中创建变量,以后就不能使用它。如果我在If块之前创建变量,并且If块的计算结果为false,则会出现“variable created and not used”错误 我确信这是故意的,我正试图做一些我不应该做的事情,但我试图做的事情背后的逻辑对我来说是有意义的。如果url中有页面信息,我希望稍后在sql语句中使用它,但是如果url中没有页面信息,那么我不需要这些变量 编辑:以下是代码: var pageID string var offset int if len(r.URL.

如果我在If块中创建变量,以后就不能使用它。如果我在If块之前创建变量,并且If块的计算结果为false,则会出现“variable created and not used”错误

我确信这是故意的,我正试图做一些我不应该做的事情,但我试图做的事情背后的逻辑对我来说是有意义的。如果url中有页面信息,我希望稍后在sql语句中使用它,但是如果url中没有页面信息,那么我不需要这些变量

编辑:以下是代码:

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
块中没有使用声明的变量。您的代码:

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
块的末尾有效(其范围在最内部包含的块的末尾结束)

解决方案是(您最可能想要的)简单地使用赋值
=
(它将值赋值给现有变量):


要使其理解,请参见以下示例:

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)
输出(在上尝试):


如果在
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
块的末尾有效(其范围在最内部包含的块的末尾结束)

解决方案是(您最可能想要的)简单地使用赋值
=
(它将值赋值给现有变量):


要使其理解,请参见以下示例:

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)
输出(在上尝试):


谢谢,我绝对不是想重新初始化pageID。偏移量呢,错误:=。。。既然err是一个新变量?假设我只是在初始化err,因为偏移量已经存在,我以后需要该值?@sup3rs3nior它将创建2个新变量,因为
offset
是在包含的块中声明的。但是请阅读,因为使用短变量声明,其中1个变量是新的,1个变量已经存在,并且它在同一块中声明,这是一个重新声明,它将只为现有的变量分配一个新值。我不确定是否应该使用短变量声明。若我使用它,我得到初始化的变量,并没有使用,若我并没有,我得到未定义的@sup3rs3nior由于希望值在块之后可见,因此不能/musn使用短变量声明。因此,您必须使用赋值
=
。但赋值要求所有变量都在前面声明。因此,在调用
loader()
之前,先声明
err
变量,例如
var err string
。请参阅工作示例:我有点担心,我第一次看到在获取值之前初始化错误是在我的代码中。你认为这表明我做错了什么吗?谢谢,我绝对不是有意要重新初始化pageID。偏移量呢,错误:=。。。既然err是一个新变量?假设我只是在初始化err,因为偏移量已经存在,我以后需要该值?@sup3rs3nior它将创建2个新变量,因为
offset
是在包含的块中声明的。但是请阅读,因为使用短变量声明,其中1个变量是新的,1个变量已经存在,并且它在同一块中声明,这是一个重新声明,它将只为现有的变量分配一个新值。我不确定是否应该使用短变量声明。若我使用它,我得到初始化的变量,并没有使用,若我并没有,我得到未定义的@sup3rs3nior由于希望值在块之后可见,因此不能/musn使用短变量声明。因此,您必须使用赋值
=
。但赋值要求所有变量都在前面声明。因此,在调用
loader()
之前,先声明
err
变量,例如
var err string
。请参阅工作示例:我有点担心,我第一次看到在获取值之前初始化错误是在我的代码中。你认为这表明我做错了什么吗?