这个Go打印语句的顺序是什么?

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

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 (
    &quot;fmt&quot;
    &quot;math&quot;
)

func pow(x, n, lim float64) float64 {
    if v := math.Pow(x, n); v &lt; lim {
	    return v
    } else {
	    fmt.Printf(&quot;%g &gt;= %g\n&quot;, v, lim)
    }
    // can&#39;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 &quot;fmt&quot;

func main() {

	fmt.Println(9, f())
}
func f() int {
	fmt.Println(&quot;This gets printed before&quot;)
	return 20
}

Output:

This gets printed before
9 20

huangapple
  • 本文由 发表于 2015年9月17日 05:07:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/32618724.html
匿名

发表评论

匿名网友

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

确定