Perbedaan antara fmt.Println () dan println () di Go

117

Seperti yang diilustrasikan di bawah, keduanya fmt.Println()dan println()memberikan output yang sama di Go:Hello world!

Tetapi: bagaimana mereka berbeda satu sama lain?

Cuplikan 1, menggunakan fmtpaket;

package main

import (
    "fmt"
)

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

Snippet 2, tanpa fmtpaket;

package main

func main() {
    println("Hello world!")
}
YulCheney
sumber

Jawaban:

98

printlnadalah fungsi bawaan (ke dalam runtime) yang pada akhirnya dapat dihapus, saat fmtpaket berada di pustaka standar, yang akan tetap ada. Lihat spesifikasi tentang topik itu.

Untuk pengembang bahasa, sangat berguna untuk memiliki printlntanpa ketergantungan, tetapi cara untuk pergi adalah dengan menggunakan fmtpaket atau yang serupa ( logmisalnya).

Seperti yang dapat Anda lihat dalam implementasinya , print(ln)fungsi tidak dirancang untuk mendukung mode keluaran yang berbeda dari jarak jauh dan terutama merupakan alat debug.

nemo
sumber
108

Untuk membangun jawaban nemo:

printlnadalah fungsi yang dibangun ke dalam bahasa. Itu ada di bagian Bootstrap dari spesifikasi . Dari tautan:

Implementasi saat ini menyediakan beberapa fungsi bawaan yang berguna selama bootstrap. Fungsi-fungsi ini didokumentasikan untuk kelengkapan tetapi tidak dijamin tetap dalam bahasa tersebut. Mereka tidak memberikan hasil.

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

Jadi, mereka berguna bagi pengembang, karena mereka kekurangan ketergantungan (dibangun ke dalam kompiler), tetapi tidak dalam kode produksi. Penting juga untuk dicatat itu printdan println laporkan ke stderr, bukanstdout .

Keluarga yang disediakan oleh fmt, bagaimanapun, dibangun untuk menjadi kode produksi. Mereka melapor ke stdout, kecuali ditentukan lain. Mereka lebih fleksibel ( fmt.Fprint*dapat melaporkan ke salah io.Writer, seperti os.Stdout, os.Stderr, atau bahkan net.Connjenis.) Dan tidak implementasi tertentu.

Kebanyakan paket yang bertanggung jawab untuk keluaran memiliki fmtketergantungan, seperti log. Jika program Anda akan mengeluarkan apa pun dalam produksi, fmtkemungkinan besar paket yang Anda inginkan.

Alexander Bauer
sumber
3

Saya dapat melihat perbedaannya di sini:

rangeOverIntsAndStrings (1, 5)

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

// keluaran

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

vs.

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

// keluaran

1
5
R Sun
sumber
1

Adapun perbedaannya, ini adalah contoh.

println() mencetak titik penunjuk ke alamat uji fungsi.

fmt.Println() mencetak alamat fungsi.

Steven
sumber
11
Saya tidak mengerti apa yang ingin Anda katakan.
Pierrot
0

Contoh Menarik:

  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

Ini adalah sesuatu yang berbeda antara printlndan fmt.Printf.

g10guang.dll
sumber