Menu

Printf dan Sprintf di Golang: Cheat Sheet Format Verb fmt

Cara package fmt di Go mencetak dan memformat nilai: Println vs Printf vs Sprintf vs Errorf, tabel lengkap format verb (%v, %+v, %d, %s, %q, %f, %T, %w, dan lainnya), width, presisi, dan padding.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Package fmt punya tiga keluarga fungsi cetak, dan setiap keluarga punya tiga varian yang sama:

FungsiOutput dikirim keFormat
Print, Println, Printfstandard outputdefault, default dengan spasi dan baris baru, string format
Sprint, Sprintln, Sprintfstring yang dikembalikantiga gaya yang sama
Fprint, Fprintln, Fprintfio.Writer apa pun (file, buffer, respons HTTP)tiga gaya yang sama
Errorferror yang dikembalikanstring format, ditambah %w untuk membungkus

Println menambahkan spasi di antara operand dan baris baru di akhir. Printf tidak menambahkan apa-apa: kamu sendiri yang menulis \n. Print menambahkan spasi hanya di antara operand yang keduanya bukan string, dan itu cukup mengejutkan sehingga kebanyakan kode memakai Println atau Printf.

Format Verb

Umum

VerbMencetakContoh output
%vnilai dalam format default{Ana 31 [admin]}
%+vstruct beserta nama field-nya{Name:Ana Age:31 Tags:[admin]}
%#vsintaks Go untuk nilai tersebutmain.User{Name:"Ana", Age:31, Tags:[]string{"admin"}}
%Ttipenyamain.User
%%tanda persen literal%

%+v adalah pilihan utama saat debugging. Pointer ke struct dicetak sebagai &{...}, bukan alamat. Map dicetak dengan key yang terurut, jadi output-nya stabil meskipun urutan iterasi map acak.

Integer

VerbArtifmt.Sprintf(verb, 255)
%ddesimal255
%bbiner11111111
%ooktal377
%Ooktal dengan prefiks 0o0o377
%x / %Xheksadesimal, huruf kecil atau besarff / FF
%#xheksadesimal dengan prefiks 0x0xff
%ckarakter dengan code point tersebutÿ
%qliteral karakter dalam tanda kutip'ÿ'
%Uformat UnicodeU+00FF

Float

VerbArtifmt.Sprintf(verb, 1234.5678)
%fdesimal, 6 angka di belakang koma secara default1234.567800
%.2fdesimal, 2 angka di belakang koma1234.57
%enotasi ilmiah1.234568e+03
%g%e atau %f, mana yang lebih pendek, tanpa nol di akhir1234.5678
%vsama dengan %g1234.5678

%.2f membulatkan nilai biner eksak dari float itu, jadi fmt.Sprintf("%.2f", 2.675) menghasilkan 2.67: float64 terdekat dengan 2,675 sedikit lebih kecil dari angka itu. Jangan pernah memformat uang dari float; simpan sen dalam integer.

String dan byte

VerbArtifmt.Sprintf(verb, "go\n")
%sstring apa adanyago dan baris baru
%qdalam tanda kutip ganda, escape ditampilkan"go\n"
%xheksadesimal dari setiap byte676f0a
% xheksadesimal dengan spasi67 6f 0a

%s pada []byte mencetaknya sebagai teks; %v mencetak angka-angkanya ([104 105]).

Tipe lain

VerbTipeMencetak
%tbooltrue atau false
%ppointer, slice, map, channel, funcalamatnya, seperti 0xc000012345
%werror (hanya di Errorf)pesan error-nya, sekaligus membungkusnya

Width, Presisi, dan Padding

Di antara % dan verb, kamu bisa menaruh flag, width, dan presisi:

BentukEfek
%5dwidth 5, rata kanan (diisi spasi di kiri)
%-5dwidth 5, rata kiri
%05ddiisi dengan nol
%.2f2 digit di belakang titik desimal
%8.2fwidth 8 dan 2 angka desimal
%.3spaling banyak 3 karakter dari string
%+dselalu tampilkan tanda
%*dwidth diambil dari argumen berikutnya

Perhatikan bahwa %.0f dari 2.5 mencetak 2: di sini Go membulatkan setengah ke angka genap. Width menghitung rune untuk string, bukan kolom tampilan, jadi karakter CJK dan emoji masih bisa membuat tabel tidak rata. Untuk kolom teks dengan panjang yang berbeda-beda, text/tabwriter melakukan pengukurannya untukmu.

Indeks argumen

%[n] memilih argumen berdasarkan posisinya, sehingga kamu bisa memakai satu argumen berulang kali:

fmt.Printf("%[2]s %[1]s\n", "world", "hello") // hello world
fmt.Printf("%d %[1]x %[1]b\n", 10)             // 10 a 1010

Errorf dan %w

fmt.Errorf membuat error dari string format. Dengan %w, fungsi ini juga membungkus error lain, sehingga pemanggil masih bisa mendeteksi error aslinya:

Pakai %w saat pemanggil mungkin perlu memeriksa penyebabnya, dan %v saat kamu sengaja menyembunyikannya. Sejak Go 1.20, satu pemanggilan Errorf boleh berisi beberapa verb %w. Halaman penanganan error membahas wrapping secara mendalam.

Format Kustom dengan String()

Tipe apa pun yang punya method String() string mengatur cara %v, %s, dan Println menampilkannya:

%d melewati String() dan mencetak angka di baliknya. Untuk tipe error, method yang setara adalah Error() string, yang lebih diutamakan daripada String().

Saat Verb-nya Salah

fmt tidak pernah panic karena format yang salah. Ia mencetak masalahnya di tempat:

fmt.Printf("%d\n", "oops")
fmt.Printf("%d %d\n", 1)
fmt.Printf("%d\n", 1, 2)
%!d(string=oops)
1 %!d(MISSING)
1
%!(EXTRA int=2)

Output seperti itu cenderung lolos sampai ke produksi karena tidak membuat apa pun crash. go vet menangkap ketiganya saat build:

./main.go:8:2: fmt.Printf format %d has arg "oops" of wrong type string
./main.go:9:2: fmt.Printf format %d reads arg #2, but call has 1 arg
./main.go:10:2: fmt.Printf call needs 1 arg but has 2 args

Catatan Performa

fmt menerima setiap argumen sebagai any dan memeriksa tipenya saat program berjalan (memakai reflection untuk struct, slice, dan map), dan itu tidak masalah untuk logging dan output, tetapi terasa di loop yang ketat. Untuk mengonversi satu angka, strconv.Itoa dan strconv.FormatFloat lebih cepat dari Sprintf. Untuk membangun string panjang di dalam loop, tulis ke strings.Builder dengan fmt.Fprintf(&b, ...) alih-alih menyambung hasil-hasil Sprintf.

Pertanyaan yang sering diajukan

Apa bedanya Println, Printf, dan Sprintf di Go?

fmt.Println mencetak argumennya dengan dipisahkan spasi dan baris baru di akhir. fmt.Printf mencetak sesuai string format dan tidak menambahkan baris baru. fmt.Sprintf memformat dengan cara yang sama seperti Printf, tetapi mengembalikan hasilnya sebagai string alih-alih mencetaknya. fmt.Errorf melakukan hal yang sama dan mengembalikan error.

Bagaimana cara mencetak struct beserta nama field-nya di Go?

Pakai %+v: fmt.Printf("%+v\n", user) mencetak {Name:Ana Age:31}. %v hanya mencetak nilainya, {Ana 31}, dan %#v mencetak sintaks Go termasuk tipenya, main.User{Name:"Ana", Age:31}.

Bagaimana cara memformat float menjadi 2 angka di belakang koma di Go?

Pakai %.2f: fmt.Sprintf("%.2f", 3.14159) mengembalikan "3.14". Tambahkan width untuk meratakan kolom, %8.2f, atau tanda minus untuk rata kiri, %-8.2f. strconv.FormatFloat(f, 'f', 2, 64) memberi hasil yang sama tanpa string format.

Apa fungsi %w di fmt.Errorf?

%w memformat error seperti %v sekaligus membungkusnya, jadi error yang baru membawa error aslinya. errors.Is dan errors.As lalu bisa menemukan error yang dibungkus itu: err := fmt.Errorf("load config: %w", os.ErrNotExist) membuat errors.Is(err, os.ErrNotExist) bernilai true. %w hanya berfungsi di fmt.Errorf.

Kenapa output saya menampilkan %!d(string=...)?

Verb-nya tidak cocok dengan tipe argumennya, misalnya %d yang diberi string. fmt mencetak masalahnya di tempat alih-alih panic: %!d(string=oops). Argumen yang kurang mencetak %!d(MISSING) dan yang berlebih mencetak %!(EXTRA int=2). go vet menangkap ketiganya sebelum kamu menjalankan program.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai