Een Go-tekenreeks formatteren zonder af te drukken?

jun 28, 2021
admin

Eenvoudige tekenreeksen

Voor “eenvoudige” tekenreeksen (meestal wat in een regel past) is de eenvoudigste oplossing het gebruik van fmt.Sprintf() en vrienden (fmt.Sprint(), fmt.Sprintln()). Deze zijn analoog aan de functies zonder de beginletter S, maar deze Sxxx() varianten geven het resultaat terug als een string in plaats van ze af te drukken naar de standaarduitvoer.

Voorbeeld:

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

De variabele s zal worden geïnitialiseerd met de waarde:

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

Tip: Als u alleen waarden van verschillende typen wilt samenvoegen, hoeft u niet automatisch Sprintf() te gebruiken (die een format string vereist), aangezien Sprint() precies dit doet. Zie dit voorbeeld:

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

Voor het aaneenschakelen van alleen strings, kunt u ook strings.Join() gebruiken, waar u een aangepast scheidingsteken string kunt opgeven (dat tussen de aan te sluiten strings moet worden geplaatst).

Probeer deze op de Go Playground.

Complexe strings (documenten)

Als de string die u probeert te maken complexer is (bijvoorbeeld een e-mail bericht van meerdere regels), wordt fmt.Sprintf() minder leesbaar en minder efficiënt (vooral als u dit vele malen moet doen).

Voor dit doel biedt de standaard bibliotheek de pakketten text/template en html/template. Deze pakketten implementeren data-driven sjablonen voor het genereren van tekstuele output. html/template is voor het genereren van HTML-uitvoer die veilig is tegen code-injectie. Het biedt dezelfde interface als pakket text/template en moet worden gebruikt in plaats van text/template wanneer de output HTML is.

Het gebruik van de template pakketten vereist in feite dat u een statisch sjabloon in de vorm van een string waarde (die kan afkomstig zijn van een bestand in welk geval u alleen de bestandsnaam verstrekt) die statische tekst kan bevatten, en acties die worden verwerkt en uitgevoerd wanneer de motor het sjabloon verwerkt en de output genereert.

U kunt parameters opgeven die in het statische sjabloon worden opgenomen/vervangen en die het proces voor het genereren van de uitvoer kunnen regelen. Typische vorm van dergelijke parameters zijn structs en map-waarden die mogen worden genest.

Voorbeeld:

Zo wilt u bijvoorbeeld e-mailberichten genereren die er als volgt uitzien:

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

Om e-mailberichtlichamen als deze te genereren, zou u het volgende statische sjabloon kunnen gebruiken:

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}}`

En de volgende gegevens verstrekken om het uit te voeren:

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

Normaal gesproken wordt de uitvoer van sjablonen geschreven naar een io.Writer, dus als u het resultaat als een string wilt, moet u een bytes.Buffer maken en schrijven naar een bytes.Buffer (die io.Writer implementeert). Het uitvoeren van het sjabloon en het verkrijgen van het resultaat als 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()

Dit zal resulteren in de verwachte output:

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

Probeer het op de Go Playground.

Merk ook op dat sinds Go 1.10, een nieuwer, sneller, meer gespecialiseerd alternatief beschikbaar is voor bytes.Buffer en dat is: strings.Builder. Het gebruik is zeer vergelijkbaar:

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

Probeer deze eens op de Go Playground.

Note: je kunt ook het resultaat van een template executie laten zien als je os.Stdout als doel opgeeft (die ook io.Writer implementeert):

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

Dit zal het resultaat direct naar os.Stdout schrijven. Probeer dit op de Go Playground.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.