Formattare una stringa Go senza stampare?

Giu 28, 2021
admin

Semplici stringhe

Per le stringhe “semplici” (tipicamente ciò che entra in una riga) la soluzione più semplice è usare fmt.Sprintf() e amici (fmt.Sprint(), fmt.Sprintln()). Queste sono analoghe alle funzioni senza la lettera iniziale S, ma queste varianti Sxxx() restituiscono il risultato come un string invece di stamparlo sullo standard output.

Per esempio:

s := fmt.Sprintf("Hi, my name is %s and I'm %d years old.", "Bob", 23)

La variabile s sarà inizializzata con il valore:

Hi, my name is Bob and I'm 23 years old.

Suggerimento: Se volete solo concatenare valori di tipi diversi, potreste non aver bisogno di usare automaticamente Sprintf() (che richiede una stringa di formato) poiché Sprint() fa esattamente questo. Vedi questo esempio:

i := 23s := fmt.Sprint("") // s will be ""

Per concatenare solo strings, puoi anche usare strings.Join() dove puoi specificare un separatore personalizzato string (da mettere tra le stringhe da unire).

Prova questi sul Go Playground.

Stringhe complesse (documenti)

Se la stringa che state cercando di creare è più complessa (ad esempio un messaggio di posta elettronica multilinea), fmt.Sprintf() diventa meno leggibile e meno efficiente (specialmente se dovete farlo molte volte).

Per questo la libreria standard fornisce i pacchetti text/template e html/template. Questi pacchetti implementano modelli guidati dai dati per generare l’output testuale. html/template è per generare output HTML sicuro contro l’iniezione di codice. Fornisce la stessa interfaccia del pacchetto text/template e dovrebbe essere usato al posto di text/template ogni volta che l’output è HTML.

Utilizzare i pacchetti template richiede fondamentalmente di fornire un template statico nella forma di un valore string (che può provenire da un file, nel qual caso si fornisce solo il nome del file) che può contenere testo statico, e azioni che sono processate ed eseguite quando il motore processa il template e genera l’output.

Puoi fornire parametri che sono inclusi/sostituiti nel template statico e che possono controllare il processo di generazione dell’output. La forma tipica di tali parametri sono i valori structs e mapche possono essere annidati.

Esempio:

Per esempio, diciamo che vuoi generare messaggi email che assomigliano a questo:

Hi !Your account is ready, your user name is: You have the following roles assigned:, , ... 

Per generare corpi di messaggi email come questo, potresti usare il seguente template statico:

const emailTmpl = `Hi {{.Name}}!Your account is ready, your user name is: {{.UserName}}You have the following roles assigned:{{range $i, $r := .Roles}}{{if $i}}, {{end}}{{.}}{{end}}`

E fornire dati come questo per l’esecuzione:

data := mapinterface{}{ "Name": "Bob", "UserName": "bob92", "Roles": string{"dbteam", "uiteam", "tester"},}

Normalmente l’output dei template viene scritto in un io.Writer, quindi se vuoi il risultato come un string, crea e scrivi in un bytes.Buffer (che implementa io.Writer). Eseguendo il template e ottenendo il risultato come string:

t := template.Must(template.New("email").Parse(emailTmpl))buf := &bytes.Buffer{}if err := t.Execute(buf, data); err != nil { panic(err)}s := buf.String()

Questo risulterà nell’output previsto:

Hi Bob!Your account is ready, your user name is: bob92You have the following roles assigned:dbteam, uiteam, tester

Provalo sul Go Playground.

Si noti inoltre che da Go 1.10, è disponibile un’alternativa più nuova, veloce e specializzata a bytes.Buffer che è: strings.Builder. L’uso è molto simile:

builder := &strings.Builder{}if err := t.Execute(builder, data); err != nil { panic(err)}s := builder.String()

Prova questo sul Go Playground.

Nota: puoi anche visualizzare il risultato dell’esecuzione di un template se fornisci os.Stdout come target (che implementa anche io.Writer):

t := template.Must(template.New("email").Parse(emailTmpl))if err := t.Execute(os.Stdout, data); err != nil { panic(err)}

Questo scriverà il risultato direttamente su os.Stdout. Provate questo sul Go Playground.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.