在go中,如果我们想要打印一些东西,我们可以这样做:
import "fmt"
func main(){
fmt.Println("Hello world!")
}
但我发现可以在不导入fmt
的情况下做同样的事情:
func main(){
println("Hello world!")
}
有人可以解释一下吗?
答案 0 :(得分:95)
以nemo的答案为基础:
println
是一种内置于该语言中的函数。它位于spec的Bootstrapping部分。从链接:
当前的实现提供了几个有用的内置函数 在自举期间。记录这些功能是为了完整性 但不保证保持语言。他们没有返回 结果
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
因此,它们对开发人员很有用,因为它们缺少依赖性(内置于编译器中),但不包含在生产代码中。同样重要的是要注意print
和println
向stderr
报告,而不是stdout
。
然而,fmt
提供的系列是在生产代码中构建的。除非另有说明,否则它们可预测地报告给stdout
。它们更通用(fmt.Fprint*
可以向任何io.Writer
报告,例如os.Stdout
,os.Stderr
,甚至是net.Conn
类型。)并且不是特定于实现的
大多数负责输出的软件包都有fmt
作为依赖项,例如log
。如果您的程序将在生产中输出任何内容,fmt
很可能是您想要的包。
答案 1 :(得分:78)
println
是一个内置函数(进入运行时),最终可能被删除,而fmt
包在标准库中,它将持久存在。有关该主题,请参阅the spec。
对于语言开发人员来说,拥有println
没有依赖关系是很方便的,但是要采用fmt
包或类似的东西(例如log
)。
尽可能see in the implementation print(ln)
函数甚至不能远程支持不同的输出模式,主要是调试工具。
答案 2 :(得分:2)
答案 3 :(得分:1)
我可以在这里看到区别:
rangeOverIntsAndStrings(1,5)
func rangeOverIntsAndStrings(args ...interface{}) {
for _, v := range args {
println(v)
}
}
//输出
(0x108f060,0x10c5358)
(0x108f060,0x10c5360)
vs
func rangeOverIntsAndStrings(args ...interface{}) {
for _, v := range args {
fmt.Println(v)
}
}
//输出
1
5
答案 4 :(得分:0)
有趣的例子:
➜ 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
println
和fmt.Printf
之间有些不同。