英文:
Why use a statement inside an "if" statement?
问题
Go tour展示了一个例子,在同一行中,他们在“if”语句中有一个额外的语句,并且他们这样解释它:if语句可以以一个短语句开始,在条件之前执行。
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
我不明白为什么需要这种语法,我觉得它非常令人困惑。为什么不在前一行中直接写v := math.Pow(x, n)
?
我之所以问这个问题,是因为根据我所了解的,Go语言中的语法经过深思熟虑后才会出现,没有什么是凭空出现的。
我猜我的实际问题是:他们使用这种语法来解决什么具体的问题?使用它能获得什么之前没有的好处?
英文:
The Go tour shows an example where they have an extra statement in the same line as the "if" statement and they explain it like this: the if statement can start with a short statement to execute before the condition.
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
I don't see the need for this syntax and find it very confusing. Why not just write v := math.Pow(x, n)
in the previous line?
The reason I'm asking is that for what I'm finding out, syntax finds its way into the Go language after careful consideration and nothing seems to be there out of whim.
I guess my actual question would be: What specific problem are they trying to solve by using this syntax? What do you gain by using it that you didn't have before?
答案1
得分: 8
有许多用例,我认为这个特性并没有解决一个具体的问题,而是针对在使用Go编码时遇到的一些问题提供了一种实用的解决方案。这种语法背后的基本意图是:
- 适当的作用域:只给变量赋予它需要的作用域
- 适当的语义:明确变量只属于代码的特定条件部分
以下是我记得的一些例子:
有限的作用域:
if v := computeStuff(); v == expectedResult {
return v
} else {
// v 在这里也是有效的
}
// 继续进行,不必担心 v
错误检查:
if perr, ok := err.(*os.PathError); ok {
// 特定处理路径错误
}
或者更一般的,类型检查:
if someStruct, ok := someInterface.(*SomeStruct); ok {
// someInterface 实际上是 *SomeStruct。
}
在映射中检查键:
if _, ok := myMap[someKey]; ok {
// 键存在
}
英文:
There are many use cases and I do not think this feature tackles a specific problem but is rather a pragmatic solution for some problems you encounter when you code in Go. The basic intentions behind the syntax are:
- proper scoping: Give a variable only the scope that it needs to have
- proper semantics: Make it clear that a variable only belongs to a specific conditional part of the code
Some examples that I remember off the top of my head:
Limited scopes:
if v := computeStuff(); v == expectedResult {
return v
} else {
// v is valid here as well
}
// carry on without bothering about v
Error checking:
if perr, ok := err.(*os.PathError); ok {
// handle path error specifically
}
or more general, Type checking:
if someStruct, ok := someInterface.(*SomeStruct); ok {
// someInterface is actually a *SomeStruct.
}
Key checking in maps:
if _, ok := myMap[someKey]; ok {
// key exists
}
答案2
得分: 2
因此,您的变量都包含在作用域中。请注意,这些v
是在不同的作用域中声明的。
一个更直接的示例来理解作用域:http://play.golang.org/p/fInnIkG5EH
package main
import (
"fmt"
)
func main() {
var hello = "Hello"
{
hello := "这是另一个"
fmt.Println(hello)
}
if hello := "新的Hello"; hello != ""{
fmt.Println(hello)
}
fmt.Println(hello)
}
英文:
Because so your variables are contained in the scope
Notice that those v
are declared on different scope.
A more direct example to understand scopes: http://play.golang.org/p/fInnIkG5EH
package main
import (
"fmt"
)
func main() {
var hello = "Hello"
{
hello := "This is another one"
fmt.Println(hello)
}
if hello := "New Hello"; hello != ""{
fmt.Println(hello)
}
fmt.Println(hello)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论