Função ToString () em Go

92

A strings.Joinfunção aceita fatias de strings apenas:

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

Mas seria bom ser capaz de passar objetos arbitrários que implementam uma ToString()função.

type ToStringConverter interface {
    ToString() string
}

Existe algo assim em Go ou eu tenho que decorar tipos existentes, como os intmétodos ToString, e escrever um invólucro strings.Join?

func Join(a []ToStringConverter, sep string) string
deamon
fonte
7
Observe que essa interface já existe: golang.org/pkg/fmt/#Stringer
Denys Séguret
@daemon Não vejo a necessidade desta duplicata. A presente questão foi suficientemente clara em minha opinião e o fato de não haver uma resposta real (ou completa) não significa que você tenha que perguntar novamente.
Denys Séguret

Respostas:

178

Anexe um String() stringmétodo a qualquer tipo nomeado e aproveite qualquer funcionalidade "ToString" personalizada:

package main

import "fmt"

type bin int

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

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

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


Resultado

101010
zzzz
fonte
1
Você está certo, embora a resposta não implique que a conversão seja a única opção. O ponto está no método String () anexado a um tipo. Anywhere fmt. * Encontra esse método anexado, ele o usa para obter a representação de string desse tipo.
zzzz
2
adicionar bin(42).String()como outro exemplo será melhor para a resposta.
Thellimist
NOTA: a função Error() stringtem maior prioridade do queString() string
Geln Yang
1
Em outras palavras, implemente a Stringerinterface: golang.org/pkg/fmt/#Stringer
tothemario
16

Quando você tem o próprio struct, você pode ter a própria função de conversão em string .

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

Outro exemplo com uma estrutura:

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

Tenha cuidado ao usá-lo, a
concatenação com '+' não compila:

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

Eu prefiro algo como o seguinte:

type StringRef []byte

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



// rather silly example, but ...
fmt.Printf("foo=%s\n",StringRef("bar"))
JSS
fonte
4
Você não precisa do inútil :, (ou seja, apenas string(s)). Além disso, se bé []byteentão string(b)muito mais simples e, em seguida, o seu StringRef(b).String(). Finalmente, seu exemplo é inútil, pois %s(ao contrário %v) já imprime []byteargumentos como strings sem a cópia potencial que string(b)normalmente faz.
Dave C