Go 中 fmt.Println() 和 println() 的区别

Posted

技术标签:

【中文标题】Go 中 fmt.Println() 和 println() 的区别【英文标题】:Difference between fmt.Println() and println() in Go 【发布时间】:2013-01-18 18:28:28 【问题描述】:

如下图所示,fmt.Println()println() 在 Go 中给出相同的输出:Hello world!

但是:它们之间有何不同?

片段 1,使用 fmt 包;

package main

import (
    "fmt"
)

func main() 
    fmt.Println("Hello world!")

片段 2,没有 fmt 包;

package main

func main() 
    println("Hello world!")

【问题讨论】:

【参考方案1】:

println 是一个内置函数(在运行时中),最终可能会被删除,而fmt 包在标准库中,它将持续存在。有关该主题,请参阅 the spec。

对于语言开发人员来说,拥有一个没有依赖关系的println 很方便,但要走的路是使用fmt 包或类似的东西(例如log)。

see in the implementation 可以,print(ln) 函数甚至不是为远程支持不同的输出模式而设计的,主要是一个调试工具。

【讨论】:

【参考方案2】:

以尼莫的回答为基础:

println 是语言内置的函数。它位于spec 的引导部分。从链接:

当前的实现提供了几个有用的内置函数 在引导期间。为了完整性,记录了这些功能 但不能保证保持语言不变。他们不返回 结果。

Function   Behavior

print      prints all arguments; formatting of arguments is implementation-specific
println    like print but prints spaces between arguments and a newline at the end

因此,它们对开发人员很有用,因为它们缺少依赖项(内置于编译器中),但在生产代码中却没有。同样重要的是要注意printprintln 报告给stderr,而不是stdout

但是,fmt 提供的系列是在生产代码中构建的。除非另有说明,否则他们会按预期向stdout 报告。它们更加通用(fmt.Fprint* 可以报告给任何io.Writer,例如os.Stdoutos.Stderr,甚至是net.Conn 类型。)并且不是特定于实现的。

大部分负责输出的包都有fmt作为依赖,比如log。如果您的程序要在生产环境中输出任何内容,fmt 很可能是您想要的包。

【讨论】:

【参考方案3】:

至于区别,this 就是一个例子。

println() 打印一个指向函数测试地址的指针。

fmt.Println() 打印函数的地址。

【讨论】:

我不明白你想说什么。【参考方案4】:

我可以在这里看到区别:

rangeOverIntsAndStrings(1, 5)

func rangeOverIntsAndStrings(args ...interface) 
    for _, v := range args 
        println(v)
    

// 输出

(0x108f060,0x10c5358)
(0x108f060,0x10c5360)

func rangeOverIntsAndStrings(args ...interface) 
    for _, v := range args 
        fmt.Println(v)
    

// 输出

1
5

【讨论】:

【参考方案5】:

有趣的例子:

➜  netpoll git:(develop) ✗ cat test.go
package main

import "fmt"

func main() 
        a := new(struct)
        b := new(struct)
        println(a, b, a == b)

        c := new(struct)
        d := new(struct)
        fmt.Printf("%v %v %v\n", c, d, c == d)

➜  netpoll git:(develop) ✗ go run test.go       
0xc000074f47 0xc000074f47 false
& & true
➜  netpoll git:(develop) ✗ go run -gcflags="-m" test.go
# command-line-arguments
./test.go:12:12: inlining call to fmt.Printf
./test.go:6:10: new(struct ) does not escape
./test.go:7:10: new(struct ) does not escape
./test.go:10:10: new(struct ) escapes to heap
./test.go:11:10: new(struct ) escapes to heap
./test.go:12:35: c == d escapes to heap
./test.go:12:12: []interface  literal does not escape
<autogenerated>:1: .this does not escape
0xc000074f47 0xc000074f47 false
& & true

printlnfmt.Printf 之间有些区别。

【讨论】:

为什么你没有比较 printlnfmt.Println 而不是?

以上是关于Go 中 fmt.Println() 和 println() 的区别的主要内容,如果未能解决你的问题,请参考以下文章

go 语言中的args多参数的传递

为什么要从Go中的类型调用func?

go之变量指针引用地址

Go 中 fmt.Println() 和 println() 的区别

Go 中 channel range 的深度理解

Go语言中 Print,Println 和 Printf 的区别