Функция ToString () в Go

96

strings.JoinФункция принимает ломтики только строки:

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

Но было бы неплохо иметь возможность передавать произвольные объекты, реализующие ToString()функцию.

type ToStringConverter interface {
    ToString() string
}

Есть ли что-то подобное в Go или мне нужно украсить существующие типы, например, intметодами ToString, и написать обертку вокруг strings.Join?

func Join(a []ToStringConverter, sep string) string
Deamon
источник
7
Обратите внимание, что такой интерфейс уже существует: golang.org/pkg/fmt/#Stringer
Denys Séguret
@daemon Я не вижу необходимости в этом дубликате. На мой взгляд, данный вопрос был достаточно ясным, и тот факт, что не было реального (или полного) ответа, не означает, что вам нужно спрашивать снова.
Denys Séguret

Ответы:

183

Прикрепите String() stringметод к любому именованному типу и пользуйтесь любой настраиваемой функциональностью ToString:

package main

import "fmt"

type bin int

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

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

Площадка: http://play.golang.org/p/Azql7_pDAA


Выход

101010
zzzz
источник
1
Вы правы, хотя ответ не означает, что преобразование - единственный вариант. Дело в методе String (), прикрепленном к типу. Где угодно fmt. * Находит этот прикрепленный метод, он использует его для получения строкового представления такого типа.
zzzz
2
добавление в bin(42).String()качестве другого примера будет лучше для ответа.
Thellimist
ПРИМЕЧАНИЕ: functon Error() stringимеет более высокий приоритет, чемString() string
Geln Yang
1
Другими словами, реализуйте Stringerинтерфейс: golang.org/pkg/fmt/#Stringer
tothemario 03
18

Когда у вас есть собственный struct, у вас может быть собственная функция преобразования в строку .

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]
}
Рио
источник
4

Другой пример со структурой:

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

Будьте осторожны при его использовании,
объединение с '+' не компилируется:

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
источник
-7

Я предпочитаю что-то вроде следующего:

type StringRef []byte

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

…

// rather silly example, but ...
fmt.Printf("foo=%s\n",StringRef("bar"))
JSS
источник
4
Вам не нужно бесполезное :(т.е. просто string(s)). Кроме того , если bесть , []byteто string(b)гораздо проще , и тогда ваш StringRef(b).String(). Наконец, ваш пример бессмыслен, поскольку %s(в отличие от %v) уже печатает []byteаргументы в виде строк без потенциальной копии, которая string(b)обычно это делает.
Dave C