ToString () -Funktion in Go

91

Die strings.JoinFunktion akzeptiert nur Strings:

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

Es wäre aber schön, beliebige Objekte übergeben zu können, die eine ToString()Funktion implementieren .

type ToStringConverter interface {
    ToString() string
}

Gibt es so etwas in Go oder muss ich vorhandene Typen wie intmit ToString-Methoden dekorieren und einen Wrapper herumschreiben strings.Join?

func Join(a []ToStringConverter, sep string) string
Deamon
quelle
7
Beachten Sie, dass eine solche Schnittstelle bereits vorhanden ist: golang.org/pkg/fmt/#Stringer
Denys Séguret
@daemon Ich sehe keine Notwendigkeit für dieses Duplikat. Die vorliegende Frage war meiner Meinung nach klar genug und die Tatsache, dass es keine echte (oder vollständige) Antwort gab, bedeutet nicht, dass Sie erneut fragen müssen.
Denys Séguret

Antworten:

176

Hängen Sie eine String() stringMethode an einen beliebigen benannten Typ an und nutzen Sie alle benutzerdefinierten "ToString" -Funktionen:

package main

import "fmt"

type bin int

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

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

Spielplatz: http://play.golang.org/p/Azql7_pDAA


Ausgabe

101010
zzzz
quelle
1
Sie haben Recht, obwohl die Antwort nicht impliziert, dass die Konvertierung die einzige Option ist. Der Punkt befindet sich in der String () -Methode, die an einen Typ angehängt ist. Überall dort, wo fmt. * Diese angehängte Methode findet, wird sie verwendet, um die Zeichenfolgendarstellung eines solchen Typs zu erhalten.
zzzz
2
Das Hinzufügen bin(42).String()als weiteres Beispiel ist für die Antwort besser.
Thellimist
HINWEIS: Funktion Error() stringhat eine höhere Priorität alsString() string
Geln Yang
1
Mit anderen Worten, implementieren Sie die StringerSchnittstelle: golang.org/pkg/fmt/#Stringer
tothemario
16

Wenn Sie eine eigene haben struct, können Sie eine eigene Funktion zum Konvertieren in einen String haben .

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
quelle
4

Ein weiteres Beispiel mit einer Struktur:

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

Seien Sie vorsichtig, wenn Sie es verwenden. Die
Verkettung mit '+' wird nicht kompiliert:

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
quelle
-7

Ich bevorzuge so etwas wie das Folgende:

type StringRef []byte

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



// rather silly example, but ...
fmt.Printf("foo=%s\n",StringRef("bar"))
JSS
quelle
4
Sie brauchen nicht das Nutzlose :(dh nur string(s)). Auch wenn bes []bytedann string(b)viel einfacher ist und dann dein StringRef(b).String(). Schließlich ist Ihr Beispiel sinnlos, da %s(im Gegensatz zu %v) bereits []byteArgumente als Zeichenfolgen ohne die string(b)normalerweise übliche potenzielle Kopie gedruckt werden .
Dave C