fmt.Appendf în Go

Formatează valorile ca Sprint, Sprintf sau Sprintln, dar adaugă rezultatul la un []byte existent.

Sintaxă
func Append(b []byte, a ...any) []byte
func Appendf(b []byte, format string, a ...any) []byte
func Appendln(b []byte, a ...any) []byte

Ce face fmt.Appendf

Cele trei funcții sunt variantele lui Sprint, Sprintf și Sprintln care nu creează un text nou, ci adaugă octeții formatați la sfârșitul unui slice []byte și returnează slice-ul mărit, la fel ca append.

Sunt utile când construiești un rezultat mare din multe bucăți (un fișier, un mesaj de rețea) și vrei să refolosești același buffer, fără să creezi un text intermediar la fiecare pas. Regulile de spațiere sunt cele de la Print/Println.

Parametri

Parametru Descriere
b []byte Slice-ul la care se adaugă. Poate fi nil.
format Doar la Appendf: șablonul cu verbe %….
a ...any Valorile de formatat.

Ce returnează

Slice-ul cu octeții adăugați. Folosește întotdeauna valoarea returnată: b = fmt.Appendf(b, ...).

Exemple

Exemplul 1: Construirea unui text CSV într-un singur buffer

package main

import "fmt"

func main() {
	var buf []byte
	buf = fmt.Append(buf, "nume,oras,nota\n")
	elevi := []struct {
		nume, oras string
		nota       int
	}{{"Ana", "Iași", 10}, {"Ion", "Cluj", 8}}
	for _, e := range elevi {
		buf = fmt.Appendf(buf, "%s,%s,%d\n", e.nume, e.oras, e.nota)
	}
	buf = fmt.Appendln(buf, "total:", len(elevi))
	fmt.Print(string(buf))
}

Rezultat

nume,oras,nota
Ana,Iași,10
Ion,Cluj,8
total: 2

Exemplul 2: Refolosirea bufferului

buf[:0] păstrează memoria alocată, dar golește conținutul; la fiecare pas nu se mai alocă memorie nouă.

package main

import "fmt"

func main() {
	buf := make([]byte, 0, 64)
	for i, oras := range []string{"Iași", "Brașov", "Constanța"} {
		buf = buf[:0]
		buf = fmt.Appendf(buf, "%d. %-10s|", i+1, oras)
		fmt.Println(string(buf), "capacitate:", cap(buf))
	}
}

Rezultat

1. Iași      | capacitate: 64
2. Brașov    | capacitate: 64
3. Constanța | capacitate: 64

Greșeli frecvente

  • Ignori valoarea returnată: fmt.Appendf(buf, ...). Ca la append, slice-ul poate fi realocat; scrie buf = fmt.Appendf(buf, ...).
  • Folosești aceste funcții pentru un singur text scurt. Acolo Sprintf este mai simplu de citit; Append* ajută când refolosești bufferul de multe ori.

Comenzi înrudite

  • fmt.Printf: Afișează text formatat cu %d, %s, %.2f etc.; Sprintf returnează textul, Fprintf îl scrie într-un fișier sau alt Writer.
  • fmt.Sprint: Transformă valorile în text și îl returnează, fără să afișeze nimic; Sprintln adaugă spații și rând nou.
  • strconv.AppendInt: Adaugă un număr sau un bool, scris ca text, la sfârșitul unui []byte, fără să creeze un text intermediar.
  • bytes.Buffer: Un buffer de octeți care crește singur: scrii în el cu Write/WriteString/WriteByte/WriteRune și citești cu String() sau Bytes().