英文:
What's the order of this Go print statements?
问题
我正在进行《Go语言之旅》教程的学习,关于这段代码:
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// 不能在这里使用 v
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
输出结果应该是 "27 >= 20 9 20"。
我很困惑为什么不是 "9 27 >= 20 20"。
难道不应该先调用 pow(3,2,10) 返回 9,打印它,然后调用 pow(3,3,20) 并打印剩下的部分吗?
英文:
I'm taking 'A Tour of GO' tutorial about Golang and this code:
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// can't use v here, though
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
would print
"27 >= 20 9 20".
I'm rather confused why it's not
"9 27 >= 20 20"
Shouldn't the first call to pow(3,2,10) return 9, print it, then call pow(3,3,20) and print the rest?
答案1
得分: 7
这实际上有点微妙,让我困惑了一会儿。"秘密"在于一个函数在被调用之前必须评估其所有参数。所以它调用函数两次以得到9和20,但其中一个评估恰好调用了Println。
语言在调用函数之前评估其参数是相当直接的(当涉及到副作用时,这种部分应用是棘手的,并且主要保留给函数式语言),但是为了清晰起见,应该避免在函数评估中隐藏具有副作用(如打印)的函数。
代码可能更直接地写成:
func main() {
arg1, arg2 := pow(3, 2, 10), pow(3, 3, 20)
fmt.Println(arg1, arg2)
}
英文:
This is actually somewhat subtle and had me confused for a second. The "secret" is that a function must evaluate all its arguments before it's called. So it calls the function twice to get 9 and 20, but one of those evaluations happens to call Println.
It's fairly straightforward why the language evaluates its arguments before calling a function (that sort of partial application is tricky when side effects are involved, and is mostly reserved for functional languages), but hiding functions with side effects such as printing inside a function evaluation should probably be discouraged just for the purposes of clarity.
The code is perhaps more straightforwardly:
func main() {
arg1,arg2 := pow(3,2,10),pow(3,3,20)
fmt.Println(arg1, arg2)
}
答案2
得分: 4
fmt.Println()
在调用之前需要所有的参数。
所以,你有9个参数,但是当你获取另一个值(20)时,控制台会打印其他内容。
就像这样:
package main
import "fmt"
func main() {
fmt.Println(9, f())
}
func f() int {
fmt.Println("This gets printed before")
return 20
}
输出:
This gets printed before
9 20
英文:
fmt.Println()
needs all its parameters before it gets invoked.
So, you have 9, but while you're getting the other value (20) the console prints something else.
Is just like this:
package main
import "fmt"
func main() {
fmt.Println(9, f())
}
func f() int {
fmt.Println("This gets printed before")
return 20
}
Output:
This gets printed before
9 20
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论