<p>I was playing on <a href="https://tour.golang.org/flowcontrol/8">the Golang website</a> when this code:</p>
<pre><code>package main
import (
"fmt"
"math"
)
func Sqrt(x float64) float64 {
z := x
for i := 0; i < 10; i++ {
z = z - (z*z-x)/(2*z)
fmt.Println(z)
}
return z
}
func main() {
n := -0.5
r1 := Sqrt(n)
r2 := math.Sqrt(n)
println("result")
fmt.Println(r1)
fmt.Println(r2)
}
</code></pre>
<p>gave me this result:</p>
<pre><code>0.25
-0.875
-0.1517857142857143
1.5711659663865545
0.6264654836111277
-0.08583154272441196
2.869766350671885
1.347768069278103
0.4883921791049566
-0.26768761926971896
-0.26768761926971896
NaN
result
</code></pre>
<p>"result" got printed after r1 and r2. How is that possible?</p>
<hr/>**评论:**<br/><br/>VerilyAMonkey: <pre><p>fmt.Println goes to stdout, while println goes to stderr.</p>
<p>So, stdout is buffered, and stderr is not. That means when you print to stdout, it doesn't actually appear until the buffer gets flushed. It's more efficient that way. Whereas writing to stderr appears immediately.</p>
<p>If you write to both, that means stderr stuff can randomly appear in the middle of stdout stuff, at a spot between buffer flushes. </p></pre>au_travail: <pre><p>Well, here two prints to stdout appear before a print to stderr, when code order would suggest otherwise.</p></pre>VerilyAMonkey: <pre><p>Haha, that's true now that you mention it. So in truth, stdout and stderr are first and foremost different and therefore unsynchronized, so I guess that kind of thing can happen too. On most computers I've used it doesn't, that I've seen, and it doesn't if I run it locally, but that depends on the state of the Go Playground and also a lot of other factors outside of simply the code you're running. The Go Playground is frequently a little bit different from a normal computer when it comes to concurrency so I'm not too surprised. </p></pre>abhayakara: <pre><p>Ah. Here is your answer: <a href="http://stackoverflow.com/questions/14680255/whats-the-difference-between-fmt-println-and-println-in-go">http://stackoverflow.com/questions/14680255/whats-the-difference-between-fmt-println-and-println-in-go</a></p>
<p>To summarize, println prints to stderr, fmt.println prints to stdout.</p>
<p>(I'm a go n00b, so it was interesting for me to find the answer... :)</p></pre>nhooyr: <pre><p>It is documented at <a href="https://golang.org/pkg/builtin/#println" rel="nofollow">https://golang.org/pkg/builtin/#println</a></p></pre>au_travail: <pre><p>Yeah but why would "result" get printed after r1 and r2 in this particular case when I iterate Newton's method 10 times and not when I iterate it 9 or 11 times?</p></pre>au_travail: <pre><p>By "11 times", I mean this program:</p>
<pre><code>package main
import (
"fmt"
"math"
)
func Sqrt(x float64) float64 {
z := x
for i := 0; i < 11; i++ {
z = z - (z*z-x)/(2*z)
fmt.Println(z)
}
return z
}
func main() {
n := -0.5
r1 := Sqrt(n)
r2 := math.Sqrt(n)
println("result")
fmt.Println(r1)
fmt.Println(r2)
}
</code></pre>
<p>Only change is "10" changed into "11".</p>
<p>It gives this result:</p>
<pre><code>0.25
-0.875
-0.1517857142857143
1.5711659663865545
0.6264654836111277
-0.08583154272441196
2.869766350671885
1.347768069278103
0.4883921791049566
-0.26768761926971896
0.8000805933017697
result
0.8000805933017697
NaN
</code></pre>
<p>With "result" at the right place this time.</p></pre>rsc: <pre><p>This doesn't happen normally. It's a playground bug. Please file an issue. Thanks. </p></pre>au_travail: <pre><p>I would like to but my github account has identifying information while this reddit account doesn't and is meant to stay that way.</p></pre>tdewolff: <pre><p>So, you want to make an anonymous bug report? Why don't you make a new GitHub account just for anonymous bug reports? I fail to see why anonymity is important with such a harmless bug report though.</p></pre>au_travail: <pre><p>Anonymity is something I want for this reddit account.</p></pre>abhayakara: <pre><p>If you try to use Newton's method on a negative number, I don't think it will converge—the errors will multiply instead of canceling out. That is, z squared - x will be -2x if z is the square root of x, whereas if x were positive, z squared - x would be 0 if z were the square root of x.</p></pre>au_travail: <pre><p>I know that the square roots of a negative number are complex numbers, so I wasn't expecting a float64 sequence to converge.</p>
<p>I was just messing around.</p></pre>abhayakara: <pre><p>Oh, and why did you call println and then fmt.println? Are they printing into the same i/o buffer?</p></pre>au_travail: <pre><p>fmt.println was there already and then I decided to try stuff I read here: <a href="https://www.reddit.com/r/golang/comments/16t661/go_a_nice_language_with_an_annoying_personality/" rel="nofollow">https://www.reddit.com/r/golang/comments/16t661/go_a_nice_language_with_an_annoying_personality/</a></p>
<blockquote>
<p>You can use print and println instead of fmt.Print. It is actually better because it is easier to find debug print statements.</p>
</blockquote>
<p>I was able to see in my tries that println has a different format for floats than fmt.println</p>
<p>I see in <a href="https://golang.org/pkg/builtin/#println" rel="nofollow">https://golang.org/pkg/builtin/#println</a> that println is deprecated. How likely is it to be removed? Is fmt.println better and why?</p></pre>abhayakara: <pre><p>Apparently println is for low-level debugging, and is present even when the libraries aren't. So not really something that we need to use in regular practice.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传