Menu

Printf et Sprintf en Golang : aide-mémoire des verbes de format fmt

Comment le package fmt de Go affiche et formate des valeurs : Println, Printf, Sprintf et Errorf, le tableau complet des verbes de format (%v, %+v, %d, %s, %q, %f, %T, %w et d'autres), largeur, précision et remplissage.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Le package fmt a trois familles de fonctions d'affichage, et chaque famille a les trois mêmes variantes :

FonctionLa sortie va versFormat
Print, Println, Printfla sortie standardpar défaut, par défaut avec espaces et retour à la ligne, chaîne de format
Sprint, Sprintln, Sprintfune string renvoyéeles trois mêmes styles
Fprint, Fprintln, Fprintfn'importe quel io.Writer (fichier, buffer, réponse HTTP)les trois mêmes styles
Errorfune error renvoyéechaîne de format, plus %w pour envelopper

Println ajoute des espaces entre les opérandes et un retour à la ligne à la fin. Printf n'ajoute rien : vous écrivez \n vous-même. Print n'ajoute des espaces qu'entre deux opérandes qui ne sont ni l'un ni l'autre des chaînes, ce qui surprend assez pour que la plupart du code utilise Println ou Printf.

Verbes de format

Généraux

VerbeAfficheExemple de sortie
%vla valeur dans un format par défaut{Ana 31 [admin]}
%+vles structs avec les noms des champs{Name:Ana Age:31 Tags:[admin]}
%#vla syntaxe Go de la valeurmain.User{Name:"Ana", Age:31, Tags:[]string{"admin"}}
%Tle typemain.User
%%un signe pourcentage littéral%

%+v est celui à utiliser pour déboguer. Un pointeur vers une struct s'affiche &{...} plutôt qu'une adresse. Les maps s'affichent avec les clés triées, donc la sortie est stable même si l'ordre d'itération des maps est aléatoire.

Entiers

VerbeSignificationfmt.Sprintf(verb, 255)
%ddécimal255
%bbinaire11111111
%ooctal377
%Ooctal avec le préfixe 0o0o377
%x / %Xhexadécimal, minuscules ou majusculesff / FF
%#xhexadécimal avec le préfixe 0x0xff
%cle caractère de ce point de codeÿ
%qun littéral caractère entre apostrophes'ÿ'
%Uformat UnicodeU+00FF

Flottants

VerbeSignificationfmt.Sprintf(verb, 1234.5678)
%fdécimal, 6 chiffres après la virgule par défaut1234.567800
%.2fdécimal, 2 chiffres après la virgule1234.57
%enotation scientifique1.234568e+03
%g%e ou %f, le plus court des deux, sans zéros finaux1234.5678
%vcomme %g1234.5678

%.2f arrondit la valeur binaire exacte du flottant, donc fmt.Sprintf("%.2f", 2.675) donne 2.67 : le float64 le plus proche de 2,675 est légèrement en dessous. Ne formatez jamais de l'argent à partir d'un flottant ; gardez les centimes dans un entier.

Chaînes et octets

VerbeSignificationfmt.Sprintf(verb, "go\n")
%sla chaîne brutego et un retour à la ligne
%qentre guillemets doubles, échappements visibles"go\n"
%xhexadécimal de chaque octet676f0a
% xhexadécimal avec espaces67 6f 0a

%s sur un []byte l'affiche comme du texte ; %v affiche les nombres ([104 105]).

Autres types

VerbeTypeAffiche
%tbooltrue ou false
%ppointeur, slice, map, channel, funcl'adresse, comme 0xc000012345
%werror (uniquement dans Errorf)le message de l'erreur, et l'enveloppe

Largeur, précision et remplissage

Entre % et le verbe, vous pouvez placer des flags, une largeur et une précision :

FormeEffet
%5dlargeur 5, aligné à droite (remplissage à gauche avec des espaces)
%-5dlargeur 5, aligné à gauche
%05dremplissage avec des zéros
%.2f2 chiffres après la virgule
%8.2flargeur 8 et 2 décimales
%.3sau plus 3 caractères de la chaîne
%+dtoujours afficher le signe
%*dlargeur prise dans l'argument suivant

Notez que %.0f de 2.5 affiche 2 : Go arrondit ici au pair le plus proche. Pour les chaînes, la largeur compte les runes, pas les colonnes affichées, donc les caractères CJK et les emojis peuvent encore désaligner un tableau. Pour des colonnes alignées de texte variable, text/tabwriter fait la mesure à votre place.

Indices d'arguments

%[n] choisit un argument par sa position, ce qui permet d'en réutiliser un :

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

Errorf et %w

fmt.Errorf construit une error à partir d'une chaîne de format. Avec %w, elle enveloppe aussi une autre erreur, pour que les appelants puissent encore détecter l'originale :

Utilisez %w quand les appelants peuvent avoir besoin de vérifier la cause, et %v quand vous la masquez volontairement. Depuis Go 1.20, un appel à Errorf peut contenir plusieurs verbes %w. La page sur la gestion des erreurs traite l'enveloppement en détail.

Formatage personnalisé avec String()

Tout type doté d'une méthode String() string contrôle la façon dont %v, %s et Println l'affichent :

%d contourne String() et affiche le nombre sous-jacent. Pour les types d'erreur, la méthode équivalente est Error() string, qui a priorité sur String().

Quand le verbe est faux

fmt ne provoque jamais de panic sur un format invalide. Il affiche le problème en ligne :

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)

Cette sortie a tendance à arriver en production parce qu'elle ne fait rien planter. go vet détecte les trois à la compilation :

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

Notes de performance

fmt prend chaque argument comme un any et inspecte son type à l'exécution (en passant par la réflexion pour les structs, slices et maps), ce qui convient pour les logs et l'affichage mais se mesure dans les boucles serrées. Pour convertir un seul nombre, strconv.Itoa et strconv.FormatFloat sont plus rapides que Sprintf. Pour construire une longue chaîne dans une boucle, écrivez dans un strings.Builder avec fmt.Fprintf(&b, ...) au lieu de concaténer des résultats de Sprintf.

Questions fréquentes

Quelle est la différence entre Println, Printf et Sprintf en Go ?

fmt.Println affiche ses arguments séparés par des espaces avec un retour à la ligne à la fin. fmt.Printf affiche selon une chaîne de format et n'ajoute pas de retour à la ligne. fmt.Sprintf formate comme Printf mais renvoie le résultat sous forme de chaîne au lieu de l'afficher. fmt.Errorf fait de même et renvoie une error.

Comment afficher une struct avec les noms des champs en Go ?

Utilisez %+v : fmt.Printf("%+v\n", user) affiche {Name:Ana Age:31}. %v affiche seulement les valeurs, {Ana 31}, et %#v affiche la syntaxe Go avec le type, main.User{Name:"Ana", Age:31}.

Comment formater un float avec 2 décimales en Go ?

Utilisez %.2f : fmt.Sprintf("%.2f", 3.14159) renvoie "3.14". Ajoutez une largeur pour aligner des colonnes, %8.2f, ou un signe moins pour aligner à gauche, %-8.2f. strconv.FormatFloat(f, 'f', 2, 64) donne le même résultat sans chaîne de format.

Que fait %w dans fmt.Errorf ?

%w formate une erreur comme %v et l'enveloppe en plus, donc la nouvelle erreur transporte l'originale. errors.Is et errors.As peuvent alors retrouver l'erreur enveloppée : err := fmt.Errorf("load config: %w", os.ErrNotExist) rend errors.Is(err, os.ErrNotExist) vrai. %w ne fonctionne que dans fmt.Errorf.

Pourquoi ma sortie affiche-t-elle %!d(string=...) ?

Le verbe ne correspond pas au type de l'argument, par exemple %d avec une chaîne. fmt affiche le problème en ligne au lieu de provoquer un panic : %!d(string=oops). Les arguments manquants s'affichent %!d(MISSING) et les arguments en trop %!(EXTRA int=2). go vet détecte les trois avant que vous lanciez le programme.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER