Menu

Golang Printf ve Sprintf: fmt Format Verb'leri Kopya Kağıdı

Go'nun fmt paketi değerleri nasıl yazdırır ve biçimlendirir: Println, Printf, Sprintf ve Errorf farkları, format verb'lerinin tam tablosu (%v, %+v, %d, %s, %q, %f, %T, %w ve fazlası), genişlik, hassasiyet ve dolgu.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

fmt paketinde üç yazdırma fonksiyonu ailesi vardır ve her ailenin aynı üç çeşidi bulunur:

FonksiyonÇıktı nereye giderBiçim
Print, Println, Printfstandart çıktıvarsayılan, boşluk ve yeni satırlı varsayılan, format string'i
Sprint, Sprintln, Sprintfdöndürülen bir stringaynı üç stil
Fprint, Fprintln, Fprintfherhangi bir io.Writer (dosya, buffer, HTTP yanıtı)aynı üç stil
Errorfdöndürülen bir errorformat string'i, ayrıca sarmalamak için %w

Println işlenenler arasına boşluk, sonuna da yeni satır ekler. Printf hiçbir şey eklemez: \n'i kendiniz yazarsınız. Print yalnızca ikisi de string olmayan işlenenlerin arasına boşluk ekler; bu o kadar şaşırtıcıdır ki çoğu kod Println ya da Printf kullanır.

Format Verb'leri

Genel

VerbYazdırdığıÖrnek çıktı
%vvarsayılan biçimde değer{Ana 31 [admin]}
%+valan adlarıyla struct'lar{Name:Ana Age:31 Tags:[admin]}
%#vdeğerin Go söz dizimimain.User{Name:"Ana", Age:31, Tags:[]string{"admin"}}
%Ttipmain.User
%%düz bir yüzde işareti%

Hata ayıklarken başvurulacak verb %+v'dir. Bir struct'a işaret eden pointer bir adres yerine &{...} olarak yazdırılır. Map'ler anahtarları sıralanmış olarak yazdırılır, bu yüzden map dolaşma sırası rastgele olsa da çıktı kararlıdır.

Tam sayılar

VerbAnlamıfmt.Sprintf(verb, 255)
%donluk255
%bikilik11111111
%osekizlik377
%O0o önekli sekizlik0o377
%x / %Xonaltılık, küçük ya da büyük harfff / FF
%#x0x önekli onaltılık0xff
%co kod noktasına sahip karakterÿ
%qtırnaklı bir karakter literal'i'ÿ'
%UUnicode biçimiU+00FF

Float'lar

VerbAnlamıfmt.Sprintf(verb, 1234.5678)
%fondalık, varsayılan 6 basamak1234.567800
%.2fondalık, 2 basamak1234.57
%ebilimsel gösterim1.234568e+03
%g%e ya da %f, hangisi kısaysa, sondaki sıfırlar olmadan1234.5678
%v%g ile aynı1234.5678

%.2f, float'ın kesin ikili değerini yuvarlar, bu yüzden fmt.Sprintf("%.2f", 2.675) sonucu 2.67'dir: 2.675'e en yakın float64 ondan biraz küçüktür. Parayı asla bir float'tan biçimlendirmeyin; kuruşları bir tam sayıda tutun.

String'ler ve byte'lar

VerbAnlamıfmt.Sprintf(verb, "go\n")
%sdüz stringgo ve bir yeni satır
%qçift tırnaklı, kaçış dizileri görünür"go\n"
%xher baytın onaltılık değeri676f0a
% xboşluklu onaltılık67 6f 0a

Bir []byte üzerinde %s onu metin olarak yazdırır; %v ise sayıları yazdırır ([104 105]).

Diğer tipler

VerbTipYazdırdığı
%tbooltrue ya da false
%ppointer, slice, map, channel, func0xc000012345 gibi adres
%werror (yalnızca Errorf içinde)hatanın mesajı, ve onu sarmalar

Genişlik, Hassasiyet ve Dolgu

% ile verb arasına bayraklar, bir genişlik ve bir hassasiyet koyabilirsiniz:

BiçimEtkisi
%5dgenişlik 5, sağa hizalı (solu boşlukla doldurulur)
%-5dgenişlik 5, sola hizalı
%05dsıfırlarla doldur
%.2fondalık noktadan sonra 2 basamak
%8.2fgenişlik 8 ve 2 ondalık
%.3sstring'in en fazla 3 karakteri
%+dişareti her zaman göster
%*dgenişlik sonraki argümandan alınır

2.5 için %.0f'nin 2 yazdırdığına dikkat edin: Go burada yarımları çift sayıya yuvarlar. Genişlik, string'ler için ekran sütunlarını değil rune'ları sayar, bu yüzden CJK karakterleri ve emoji bir tabloyu yine de kaydırabilir. Değişken metinli hizalı sütunlar için ölçümü text/tabwriter sizin yerinize yapar.

Argüman indeksleri

%[n] bir argümanı konumuna göre seçer, bu da bir argümanı yeniden kullanmanızı sağlar:

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

Errorf ve %w

fmt.Errorf bir format string'inden bir error oluşturur. %w ile ayrıca başka bir hatayı sarmalar, böylece çağıranlar orijinali hâlâ tespit edebilir:

Çağıranların nedeni kontrol etmesi gerekebilecekse %w, nedeni bilerek gizliyorsanız %v kullanın. Go 1.20'den beri tek bir Errorf çağrısı birden fazla %w verb'ü içerebilir. Hata yönetimi sayfası sarmalamayı derinlemesine anlatıyor.

String() ile Özel Biçimlendirme

String() string metodu olan her tip, %v, %s ve Println'in onu nasıl göstereceğini kontrol eder:

%d, String()'i atlar ve temeldeki sayıyı yazdırır. Hata tipleri için eşdeğer metot Error() string'dir ve String()'den önceliklidir.

Verb Yanlış Olduğunda

fmt hatalı bir biçimde asla panic yapmaz. Sorunu satır içinde yazdırır:

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)

Bu çıktı hiçbir şeyi çökertmediği için production'a kadar ulaşma eğilimindedir. go vet üçünü de derleme zamanında yakalar:

./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

Performans Notları

fmt her argümanı bir any olarak alır ve tipini çalışma zamanında inceler (struct'lar, slice'lar ve map'ler için reflection'a başvurur); bu, loglama ve çıktı için sorun değildir ama sıkı döngülerde ölçülebilir bir maliyettir. Tek bir sayıyı dönüştürmek için strconv.Itoa ve strconv.FormatFloat, Sprintf'ten daha hızlıdır. Bir döngüde uzun bir string oluşturmak için Sprintf sonuçlarını birleştirmek yerine fmt.Fprintf(&b, ...) ile bir strings.Builder'a yazın.

Sıkça Sorulan Sorular

Go'da Println, Printf ve Sprintf arasındaki fark nedir?

fmt.Println argümanlarını boşluklarla ayırarak ve sonuna yeni satır ekleyerek yazdırır. fmt.Printf bir format string'ine göre yazdırır ve yeni satır eklemez. fmt.Sprintf, Printf ile aynı şekilde biçimlendirir ama sonucu yazdırmak yerine string olarak döndürür. fmt.Errorf de aynısını yapar ve bir error döndürür.

Go'da bir struct alan adlarıyla nasıl yazdırılır?

%+v kullanın: fmt.Printf("%+v\n", user), {Name:Ana Age:31} yazdırır. %v yalnızca değerleri yazdırır, {Ana 31}; %#v ise tip dahil Go söz dizimini yazdırır, main.User{Name:"Ana", Age:31}.

Go'da bir float 2 ondalık basamakla nasıl biçimlendirilir?

%.2f kullanın: fmt.Sprintf("%.2f", 3.14159), "3.14" döndürür. Sütunları hizalamak için bir genişlik ekleyin, %8.2f; sola hizalamak için bir eksi işareti, %-8.2f. strconv.FormatFloat(f, 'f', 2, 64) format string'i olmadan aynı sonucu verir.

fmt.Errorf içinde %w ne yapar?

%w bir hatayı %v gibi biçimlendirir ve ayrıca onu sarmalar, böylece yeni hata orijinalini taşır. errors.Is ve errors.As sonra sarmalanmış hatayı bulabilir: err := fmt.Errorf("load config: %w", os.ErrNotExist) ifadesi errors.Is(err, os.ErrNotExist) sonucunu true yapar. %w yalnızca fmt.Errorf içinde çalışır.

Çıktım neden %!d(string=...) gösteriyor?

Verb, argümanın tipiyle eşleşmiyor; örneğin %d'ye bir string verilmiş. fmt panic yerine sorunu satır içinde yazdırır: %!d(string=oops). Eksik argümanlar %!d(MISSING), fazla olanlar %!(EXTRA int=2) olarak yazdırılır. go vet üçünü de programı çalıştırmadan önce yakalar.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA