Función ToString () en Go

96

La strings.Joinfunción solo toma porciones de cadenas:

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

Pero sería bueno poder pasar objetos arbitrarios que implementan una ToString()función.

type ToStringConverter interface {
    ToString() string
}

¿Hay algo como esto en Go o tengo que decorar los tipos existentes como intcon los métodos ToString y escribir un envoltorio strings.Join?

func Join(a []ToStringConverter, sep string) string
demonio
fuente
7
Tenga en cuenta que dicha interfaz ya existe: golang.org/pkg/fmt/#Stringer
Denys Séguret
@daemon No veo la necesidad de este duplicado. En mi opinión, la pregunta actual fue lo suficientemente clara y el hecho de que no haya una respuesta real (o completa) no significa que deba volver a preguntar.
Denys Séguret

Respuestas:

183

Adjunte un String() stringmétodo a cualquier tipo con nombre y disfrute de cualquier funcionalidad personalizada "ToString":

package main

import "fmt"

type bin int

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

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

Zona de juegos: http://play.golang.org/p/Azql7_pDAA


Salida

101010
zzzz
fuente
1
Tienes razón, aunque la respuesta no implica que la conversión sea la única opción. El punto está en el método String () adjunto a un tipo. En cualquier lugar donde fmt. * Encuentre ese método adjunto, lo usa para obtener la representación de cadena de dicho tipo.
zzzz
2
agregar bin(42).String()como otro ejemplo será mejor para la respuesta.
Thellimist
NOTA: functon Error() stringtiene mayor prioridad queString() string
Geln Yang
1
En otras palabras, implemente la Stringerinterfaz: golang.org/pkg/fmt/#Stringer
tothemario
18

Cuando tenga la propia struct, podría tener su propia función de conversión a cadena .

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]
}
Río
fuente
4

Otro ejemplo con una estructura:

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

Tenga cuidado al usarlo, la
concatenación con '+' no se 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
fuente
-7

Prefiero algo como lo siguiente:

type StringRef []byte

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

…

// rather silly example, but ...
fmt.Printf("foo=%s\n",StringRef("bar"))
JSS
fuente
4
No necesitas lo inútil :(es decir, solo string(s)). Además, si bes []byteentonces string(b)mucho más simple y entonces tu StringRef(b).String(). Finalmente, su ejemplo no tiene sentido ya que %s(a diferencia de %v) ya imprime []byteargumentos como cadenas sin la copia potencial que string(b)normalmente lo hace.
Dave C