Fungsi ToString () di Go

97

The strings.JoinFungsi mengambil irisan string saja:

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

Tapi alangkah baiknya bisa melewatkan objek arbitrer yang mengimplementasikan suatu ToString()fungsi.

type ToStringConverter interface {
    ToString() string
}

Apakah ada yang seperti ini di Go atau apakah saya harus menghias tipe yang sudah ada seperti intdengan metode ToString dan menulis pembungkus strings.Join?

func Join(a []ToStringConverter, sep string) string
deamon
sumber
7
Perhatikan bahwa antarmuka seperti itu sudah ada: golang.org/pkg/fmt/#Stringer
Denys Séguret
@ daemon Saya tidak melihat kebutuhan untuk duplikat ini. Pertanyaan saat ini cukup jelas menurut saya dan fakta bahwa tidak ada jawaban yang nyata (atau lengkap) tidak berarti Anda harus bertanya lagi.
Denys Séguret

Jawaban:

183

Lampirkan String() stringmetode ke jenis bernama apa pun dan nikmati fungsi "ToString" kustom apa pun:

package main

import "fmt"

type bin int

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

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

Taman bermain: http://play.golang.org/p/Azql7_pDAA


Keluaran

101010
zzzz
sumber
1
Anda benar, meskipun jawabannya tidak menyiratkan bahwa konversi adalah satu-satunya pilihan. Intinya ada di metode String () yang dilampirkan ke sebuah tipe. Di mana saja fmt. * Menemukan metode yang dilampirkan yang digunakannya untuk mendapatkan representasi string dari tipe tersebut.
zzzz
2
menambahkan bin(42).String()sebagai contoh lain akan lebih baik untuk jawabannya.
Thellimist
CATATAN: functon Error() stringmemiliki prioritas lebih tinggi daripadaString() string
Geln Yang
1
Dengan kata lain, terapkan Stringerantarmuka: golang.org/pkg/fmt/#Stringer
tothemario
18

Bila Anda memiliki sendiri struct, Anda dapat memiliki fungsi convert-to-string sendiri .

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

Contoh lain dengan struct:

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

Hati-hati saat menggunakannya,
penggabungan dengan '+' tidak dapat dikompilasi:

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

Saya lebih suka sesuatu seperti berikut:

type StringRef []byte

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

…

// rather silly example, but ...
fmt.Printf("foo=%s\n",StringRef("bar"))
JSS
sumber
4
Anda tidak membutuhkan yang tidak berguna :, (yaitu hanya string(s)). Juga, jika bini []bytemaka string(b)jauh lebih sederhana dan kemudian Anda StringRef(b).String(). Akhirnya, contoh Anda tidak ada gunanya karena %s(tidak seperti %v) sudah mencetak []byteargumen sebagai string tanpa salinan potensial yang string(b)biasanya melakukannya.
Dave C