Formater une chaîne Go sans imprimer?

Existe-t-il un moyen simple de formater une chaîne dans Go sans imprimer la chaîne?

Je peux faire:

bar := "bar" fmt.Printf("foo: %s", bar) 

Mais je veux que la chaîne formatée soit retournée plutôt qu’imprimée afin que je puisse la manipuler davantage.

Je pourrais aussi faire quelque chose comme:

 s := "foo: " + bar 

Mais cela devient difficile à lire lorsque la chaîne de format est complexe et encombrante quand une ou plusieurs parties ne sont pas des chaînes et doivent être converties en premier, comme

 i := 25 s := "foo: " + strconv.Itoa(i) 

Je suis tout nouveau pour Go – mes antécédents sont en Ruby, où c’est simple. Y a-t-il un moyen plus simple de le faire?

Sprintf

Voici aussi une utilisation dans le tutoriel, “A Tour of Go”.

 return fmt.Sprintf("at %v, %s", e.When, e.What) 

1. cordes simples

Pour les chaînes “simples” (généralement ce qui rentre dans une ligne), la solution la plus simple consiste à utiliser fmt.Sprintf() et des amis ( fmt.Sprint() , fmt.Sprintln() ). Celles-ci sont analogues aux fonctions sans la lettre S départ, mais ces variantes Sxxx() renvoient le résultat sous forme de ssortingng au lieu de l’imprimer dans la sortie standard.

Par exemple:

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

La variable s sera initialisée avec la valeur:

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

Astuce: Si vous voulez simplement concaténer des valeurs de types différents, vous n’aurez peut-être pas besoin d’utiliser Sprintf() (qui nécessite une chaîne de format) car Sprint() fait exactement cela. Voir cet exemple:

 i := 23 s := fmt.Sprint("[age:", i, "]") // s will be "[age:23]" 

Pour concaténer uniquement des ssortingng , vous pouvez également utiliser ssortingngs.Join() où vous pouvez spécifier une ssortingng séparation personnalisée (à placer entre les chaînes à joindre).

Essayez-les sur le terrain de jeu Go .

2. chaînes complexes (documents)

Si la chaîne que vous essayez de créer est plus complexe (par exemple un message électronique multi-lignes), fmt.Sprintf() devient moins lisible et moins efficace (surtout si vous devez le faire plusieurs fois).

Pour cela, la bibliothèque standard fournit les paquets text/template et html/template . Ces packages implémentent des modèles pilotés par les données pour générer des sorties textuelles. html/template sert à générer une sortie HTML sûre contre l’injection de code. Il fournit la même interface que le text/template package et doit être utilisé à la place de text/template lorsque le résultat est HTML.

L’utilisation des packages de template nécessite essentiellement que vous fournissiez un modèle statique sous la forme d’une valeur de ssortingng (pouvant provenir d’un fichier, auquel cas vous fournissez uniquement le nom du fichier) pouvant contenir du texte statique et des actions traitées et exécutées lorsque le moteur traite le modèle et génère la sortie.

Vous pouvez fournir des parameters qui sont inclus / substitués dans le modèle statique et qui peuvent contrôler le processus de génération de sortie. La forme typique de tels parameters est struct et les valeurs de map qui peuvent être nestedes.

Exemple:

Par exemple, supposons que vous souhaitiez générer des messages électroniques ressemblant à ceci:

 Hi [name]! Your account is ready, your user name is: [user-name] You have the following roles assigned: [role#1], [role#2], ... [role#n] 

Pour générer des corps de messages tels que celui-ci, vous pouvez utiliser le modèle statique suivant:

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

Et fournissez des données comme celle-ci pour l’exécuter:

 data := map[ssortingng]interface{}{ "Name": "Bob", "UserName": "bob92", "Roles": []ssortingng{"dbteam", "uiteam", "tester"}, } 

Normalement, la sortie des modèles est écrite dans un io.Writer , donc si vous voulez le résultat sous forme de ssortingng , créez et écrivez dans un bytes.Buffer (qui implémente io.Writer ). Exécuter le template et obtenir le résultat sous forme de ssortingng :

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

Cela se traduira par la sortie attendue:

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

Essayez-le sur le terrain de jeu Go .

Notez également que depuis Go 1.10, une alternative plus récente, plus rapide et plus spécialisée est disponible pour bytes.Buffer qui est: ssortingngs.Builder . L’utilisation est très similaire:

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

Essayez celui-ci sur le terrain de jeu de Go .

Remarque: vous pouvez également afficher le résultat d’une exécution de modèle si vous fournissez os.Stdout tant que cible (qui implémente également io.Writer ):

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

Cela va écrire le résultat directement dans os.Stdout . Essayez ceci sur le terrain de jeu de Go .

Dans votre cas, vous devez utiliser Sprintf () pour la chaîne de format.

func Sprintf(format ssortingng, a ...interface{}) ssortingng

Sprintf formate selon un spécificateur de format et retourne la chaîne résultante.

s := fmt.Sprintf("Good Morning, This is %s and I'm living here from last %d years ", "John", 20)

Votre sortie sera:

Bonjour, voici John et je vis ici depuis 20 ans.

La fonction fmt.SprintF renvoie une chaîne et vous pouvez formater la chaîne de la même manière que vous le feriez avec fmt.PrintF