Fonction ToString () dans Go

92

La strings.Joinfonction prend uniquement des tranches de chaînes:

s := []string{"foo", "bar", "baz"}
fmt.Println(strings.Join(s, ", "))

Mais ce serait bien de pouvoir passer des objets arbitraires qui implémentent une ToString()fonction.

type ToStringConverter interface {
    ToString() string
}

Y a-t-il quelque chose comme ça dans Go ou dois-je décorer les types existants comme intavec les méthodes ToString et écrire un wrapper strings.Join?

func Join(a []ToStringConverter, sep string) string
démon
la source
7
Notez qu'une telle interface existe déjà: golang.org/pkg/fmt/#Stringer
Denys Séguret
@daemon Je ne vois pas la nécessité de ce duplicata. La question actuelle était assez claire à mon avis et le fait qu'il n'y ait pas de réponse réelle (ou complète) ne signifie pas que vous devez demander à nouveau.
Denys Séguret

Réponses:

178

Attachez une String() stringméthode à n'importe quel type nommé et profitez de toutes les fonctionnalités personnalisées "ToString":

package main

import "fmt"

type bin int

func (b bin) String() string {
        return fmt.Sprintf("%b", b)
}

func main() {
        fmt.Println(bin(42))
}

Aire de jeu: http://play.golang.org/p/Azql7_pDAA


Production

101010
zzzz
la source
1
Vous avez raison, bien que la réponse n'implique pas que la conversion soit la seule option. Le point est dans la méthode String () attachée à un type. Anywhere fmt. * Trouve cette méthode attachée, il l'utilise pour obtenir la représentation sous forme de chaîne de ce type.
zzzz
2
l'ajout bin(42).String()d'un autre exemple sera meilleur pour la réponse.
Thellimist
REMARQUE: functon Error() stringa une priorité plus élevée queString() string
Geln Yang
1
En d'autres termes, implémentez l' Stringerinterface: golang.org/pkg/fmt/#Stringer
tothemario
16

Lorsque vous en avez un struct, vous pouvez avoir votre propre fonction de conversion en chaîne .

package main

import (
    "fmt"
)

type Color struct {
    Red   int `json:"red"`
    Green int `json:"green"`
    Blue  int `json:"blue"`
}

func (c Color) String() string {
    return fmt.Sprintf("[%d, %d, %d]", c.Red, c.Green, c.Blue)
}

func main() {
    c := Color{Red: 123, Green: 11, Blue: 34}
    fmt.Println(c) //[123, 11, 34]
}
Rio
la source
4

Un autre exemple avec une structure:

package types

import "fmt"

type MyType struct {
    Id   int    
    Name string
}

func (t MyType) String() string {
    return fmt.Sprintf(
    "[%d : %s]",
    t.Id, 
    t.Name)
}

Attention lors de son utilisation, la
concaténation avec '+' ne compile pas:

t := types.MyType{ 12, "Blabla" }

fmt.Println(t) // OK
fmt.Printf("t : %s \n", t) // OK
//fmt.Println("t : " + t) // Compiler error !!!
fmt.Println("t : " + t.String()) // OK if calling the function explicitly
lgu
la source
-7

Je préfère quelque chose comme ce qui suit:

type StringRef []byte

func (s StringRef) String() string {
        return string(s[:])
}



// rather silly example, but ...
fmt.Printf("foo=%s\n",StringRef("bar"))
JSS
la source
4
Vous n'avez pas besoin de l'inutile :(c'est-à-dire juste string(s)). En outre, si best []bytealors string(b)beaucoup plus simple, puis votre StringRef(b).String(). Enfin, votre exemple est inutile car %s(contrairement à %v) imprime déjà les []bytearguments sous forme de chaînes sans la copie potentielle qui le fait string(b)habituellement.
Dave C