ToString()函数在Go中

huangapple go评论87阅读模式
英文:

ToString() function in Go

问题

The strings.Join function takes slices of strings only:

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

But it would be nice to be able to pass arbitrary objects which implement a ToString() function.

type ToStringConverter interface {
	ToString() string
}

Is there something like this in Go or do I have to decorate existing types like int with ToString methods and write a wrapper around strings.Join?

func Join(a []ToStringConverter, sep string) string
英文:

The strings.Join function takes slices of strings only:

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

But it would be nice to be able to pass arbitrary objects which implement a ToString() function.

type ToStringConverter interface {
	ToString() string
}

Is there something like this in Go or do I have to decorate existing types like int with ToString methods and write a wrapper around strings.Join?

func Join(a []ToStringConverter, sep string) string

答案1

得分: 255

为任何命名类型添加一个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))
}

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


输出

101010
英文:

Attach a String() string method to any named type and enjoy any custom "ToString" functionality:

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


Output

101010

答案2

得分: 28

当你拥有自己的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]
}
英文:

When you have own struct, you could have own convert-to-string function.

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

答案3

得分: 7

另一个使用结构体的示例:

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) // 正常
fmt.Printf("t : %s \n", t) // 正常
//fmt.Println("t : " + t) // 编译错误!!!
fmt.Println("t : " + t.String()) // 如果显式调用函数,则正常
英文:

Another example with a 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)
}

Be careful when using it,
concatenation with '+' doesn't compile :

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

答案4

得分: 1

   package main
    
    import "fmt"
    
    
    type Person struct {
    	fname, sname string 
    	address string 
    }
    
    
    func (p *Person) String() string {
    	s:=  fmt.Sprintf("\n %s %s  lives at %s \n", p.fname, p.sname, p.address)
    	return s
    }
    
    
    func main(){
    	alex := &Person{"Alex", "Smith", "33 McArthur Bvd"}
    	fmt.Println(alex)
    
    }

输出:

Alex Smith 住在 33 McArthur Bvd

英文:
  • This works well
   package main
    
    import "fmt"
    
    
    type Person struct {
    	fname, sname string 
    	address string 
    }
    
    
    func (p *Person) String() string {
    	s:=  fmt.Sprintf("\n %s %s  lives at %s \n", p.fname, p.sname, p.address)
    	return s
    }
    
    
    func main(){
    	alex := &Person{"Alex", "Smith", "33 McArthur Bvd"}
    	fmt.Println(alex)
    
    }

Output:

Alex Smith lives at 33 McArthur Bvd

答案5

得分: 1

如果您有一组固定的可能类型的元素可以转换,那么您可以为每个类型定义转换函数,并使用反射来测试元素的实际类型并调用相应的函数,例如:

func ToStringint(x int) string { 
  return strconv.Itoa(x)
}

func ToStringlong(x int64) string { 
  return strconv.FormatInt(x,10)
} 

func ToStringdouble(x float64) string { 
  return fmt.Sprintf("%f", x)
} 

func ToStringboolean(x bool) string {
  if x { 
    return "true"
  } 
  return "false"
} 

func ToStringOclAny(x interface{}) string { 
  if reflect.TypeOf(x) == TYPEint { 
    return strconv.Itoa(x.(int)) 
  } 

  if reflect.TypeOf(x) == TYPEdouble { 
      return fmt.Sprintf("%f", x.(float64))
  } 

  if reflect.TypeOf(x) == TYPElong { 
    return strconv.FormatInt(x.(int64),10)
  } 

  if reflect.TypeOf(x) == TYPEString { 
     return x.(string)
  } 

  if reflect.TypeOf(x) == TYPEboolean { 
     return ToStringboolean(x.(bool))
  } 

  if reflect.TypeOf(x) == TYPESequence { 
     return ToStringSequence(x.(*list.List))
  } 

  if reflect.TypeOf(x) == TYPEMap { 
     return ToStringMap(x.(map[interface{}]interface{}))
  }

  return ""
}

func ToStringSequence(col *list.List) string { 
  res := "Sequence{"
  for e := col.Front(); e != nil; e = e.Next() { 
     res = res + ToStringOclAny(e.Value)
     if e.Next() != nil { 
       res = res + ", "
    } 
  } 
  return res + "}" 
}

func ToStringSet(col *list.List) string { 
   res := "Set{"
   for e := col.Front(); e != nil; e = e.Next() { 
      res = res + ToStringOclAny(e.Value)
      if e.Next() != nil { 
         res = res + ", "
      }
   } 
   return res + "}" 
 }

func ToStringMap(m map[interface{}]interface{}) string { 
  res := "Map{"
  for i, v := range m { 
    res = res + ToStringOclAny(i) + " -> " + ToStringOclAny(v) + " "
  }
  return res + "}"
}
英文:

If you have a fixed set of possible types for elements that could be converted, then you can define conversion functions for each, and a general conversion function that uses reflection to test the actual type of an element and call the relevant function for that element, eg:

func ToStringint(x int) string { 
  return strconv.Itoa(x)
}

func ToStringlong(x int64) string { 
  return strconv.FormatInt(x,10)
} 

func ToStringdouble(x float64) string { 
  return fmt.Sprintf("%f", x)
} 

func ToStringboolean(x bool) string {
  if x { 
    return "true"
  } 
  return "false"
} 

func ToStringOclAny(x interface{}) string { 
  if reflect.TypeOf(x) == TYPEint { 
    return strconv.Itoa(x.(int)) 
  } 

  if reflect.TypeOf(x) == TYPEdouble { 
      return fmt.Sprintf("%f", x.(float64))
  } 

  if reflect.TypeOf(x) == TYPElong { 
    return strconv.FormatInt(x.(int64),10)
  } 

  if reflect.TypeOf(x) == TYPEString { 
     return x.(string)
  } 

  if reflect.TypeOf(x) == TYPEboolean { 
     return ToStringboolean(x.(bool))
  } 

  if reflect.TypeOf(x) == TYPESequence { 
     return ToStringSequence(x.(*list.List))
  } 

  if reflect.TypeOf(x) == TYPEMap { 
     return ToStringMap(x.(map[interface{}]interface{}))
  }

  return ""
}

func ToStringSequence(col *list.List) string { 
  res := "Sequence{"
  for e := col.Front(); e != nil; e = e.Next() { 
     res = res + ToStringOclAny(e.Value)
     if e.Next() != nil { 
       res = res + ", "
    } 
  } 
  return res + "}" 
}

func ToStringSet(col *list.List) string { 
   res := "Set{"
   for e := col.Front(); e != nil; e = e.Next() { 
      res = res + ToStringOclAny(e.Value)
      if e.Next() != nil { 
         res = res + ", "
      }
   } 
   return res + "}" 
 }

func ToStringMap(m map[interface{}]interface{}) string { 
  res := "Map{"
  for i, v := range m { 
    res = res + ToStringOclAny(i) + " |-> " + ToStringOclAny(v) + " "
  }
  return res + "}"
} 

答案6

得分: -2

这里有一个简单的处理方法:

package main

import (
	"fmt"
	"strconv"
)

type Person struct {
	firstName, lastName string
	age int
}

func (p Person) GetFullName() string {
	return p.firstName + " " + p.lastName
}

func (p Person) GetAge() int {
	return p.age
}

func (p Person) GetAgeAsString() string {
	return strconv.Itoa(p.age)
}

func main() {
	p := Person {"John", "Doe", 21}
	fmt.Println(p.GetFullName())
	fmt.Println(p.GetAgeAsString())
}

输出:

"John Doe"
"21"
英文:

Here is a simple way to handle this:

package main

import (
	"fat"
	"strconv"
)

type Person struct {
	firstName, lastName string
	age int
}

func (p Person) GetFullName() string {
	return p.firstName + " " + p.lastName
}

func (p Person) GetAge() int {
	return p.age
}

func (p Person) GetAgeAsString() string {
	return strconv.Itoa(p.age)
}

func main() {
	p := Person {"John", "Doe", 21}
	fmt.Println(p.GetFullName())
	fmt.Println(p.GetAgeAsString())
}

Output:

"John Doe"
"21"

答案7

得分: -8

我更喜欢以下的写法:

type StringRef []byte

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

…

// 一个有点傻的例子,但是...
fmt.Printf("foo=%s\n", StringRef("bar"))
英文:

I prefer something like the following:

type StringRef []byte

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

…

// rather silly example, but ...
fmt.Printf("foo=%s\n",StringRef("bar"))

huangapple
  • 本文由 发表于 2012年11月6日 17:02:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/13247644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定