How do I create a variable in go only if a condition is true?

huangapple go评论87阅读模式
英文:

How do I create a variable in go only if a condition is true?

问题

如果我在if块内创建一个变量,我就不能在后面使用它。如果我在if块之前创建一个变量,并且if块的条件为false,我会得到一个"变量已创建但未使用"的错误。

我确信这是按设计来的,我正在尝试做一些我不应该做的事情,但是我尝试做的事情的逻辑对我来说是有意义的。如果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 I create a variable inside an if block, I can't use it later on. If I create a variable before the if block and the if block evaluates to false, I get a "variable created and not used" error.

I'm certain that this is by design and I'm trying to do something I shouldn't, but the logic behind what I'm trying to do makes sense to me. If there is page info in the url, I want to use it in a sql statement later on, but if there isn't page info in the url, then I don't need those variables.

http://pastebin.com/QqwpdM1d

Edit: here's the code:

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 {
	// ...
}

答案1

得分: 5

如果你在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 = r.URL.Path[len("/page/"):]

为了让你理解,看看这个例子:

i := 1
fmt.Println("Outer:", i)
{
    i := 2 // 短变量声明:创建一个新的 i,遮蔽了外部的 i
    fmt.Println("Inner:", i)
}
fmt.Println("Outer again:", i)

输出结果(在Go Playground上尝试):

Outer: 1
Inner: 2
Outer again: 1
英文:

If you declare a variable before an if statement and you use it inside the if block, it doesn't matter what the condition evaluates to, it is not a compile time error.

The error in you case is that you don't use the declared variable inside the if block. Your code:

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)
    }
}

Inside the if you are not assigning to the previously declared pageID, but you are using short variable declaration := which creates a new variable, shadowing the one created in the outer block, and it is in effect only at the end of the if block (its scope ends at the end of the innermost containing block).

Solution is (what you most likely wanted to) simply use assignment = (which assigns value to the existing variable):

    pageID = r.URL.Path[len("/page/"):]

To make it understand, see this example:

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)

Output (try it on the Go Playground):

Outer: 1
Inner: 2
Outer again: 1

huangapple
  • 本文由 发表于 2016年2月21日 16:29:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/35533960.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定