如何在Go(Golang)中编写一个打印地图对象的函数?现在我有这个,但它没有编译。它返回cannot convert value (type interface {}) to type reflect.Kind: need type assertion
。
package main
type MyDictionary map[string]interface{}
func (d MyDictionary) String() string {
var stringBuffer bytes.Buffer
for key, value := range d {
stringBuffer.WriteString(key)
stringBuffer.WriteString(": ")
valueType := reflect.Kind(value)
switch valueType {
case reflect.String:
log.Println("string") // just to check if this block gets executed
// Add to stringBuffer
case reflect.Float64:
log.Println("float64") // just to check if this block gets executed
// Add to stringBuffer
default:
log.Println("Error: type was", valueType)
}
}
return stringBuffer.String()
}
func main() {
var dict MyDictionary = make(MyDictionary)
dict["hello"] = "world"
dict["floating"] = 10.0
dict["whole"] = 12
fmt.Println(dict)
}
我希望String()
返回类似hello: world\nfloating: 10.0\nwhole: 12\n
的字符串。然后我可以传递给fmt.Println()
来打印它。在Java中,我会使用StringBuilder
来实现此目的。
hello: world
floating: 10.0
whole: 12
我还尝试使用value.(type)
和case string:
切换case float64
,但后来我不知道如何将这些值写入stringBuffer
。
答案 0 :(得分:5)
这是一个惯用的解决方案。
func (d MyDictionary) String() string {
var buf bytes.Buffer
for k, v := range d {
buf.WriteString(k + ": ")
// v is an interface{} here
switch v := v.(type) {
// The inner v is typed. It shadows the outer interface{} v. That's
// the idiomatic part.
case string:
buf.WriteString(v + "\n") // v is a string
case int:
buf.WriteString(fmt.Sprintln(v)) // v is an int
case float64:
buf.WriteString(fmt.Sprintln(v)) // v is a float64
}
}
return buf.String()
}
答案 1 :(得分:1)
您可以将其简化为此(playground):
func (d MyDictionary) String() string {
var result string
for key, value := range d {
result += fmt.Sprintf("%s: %v\n", key, value)
}
return result
}
打印哪些:
hello: world
floating: 10
whole: 12
显然,"整体"浮点数已删除小数(如果将其设置为10.5
,它将正确打印)。如果需要,那么您需要启用float
并指定精度(playground):
func (d MyDictionary) String() string {
var result string
for key, value := range d {
switch value.(type) {
case float64:
result += fmt.Sprintf("%s: %.2f\n", key, value)
default:
result += fmt.Sprintf("%s: %v\n", key, value)
}
}
return result
}
打印哪些:
floating: 10.00
whole: 12
hello: world
答案 2 :(得分:-1)
您需要获取接口的类型,然后打开类型的类型。
valueType := reflect.TypeOf(value).Kind()
工作示例:http://play.golang.org/p/a-7SePUzZ-
package main
import (
"bytes"
"fmt"
"log"
"reflect"
)
type MyDictionary map[string]interface{}
func (d MyDictionary) String() string {
var stringBuffer bytes.Buffer
for key, value := range d {
stringBuffer.WriteString(key)
stringBuffer.WriteString(": ")
valueType := reflect.TypeOf(value).Kind()
switch valueType {
case reflect.String:
log.Println("string")
default:
log.Println("Type was:", valueType)
}
}
return stringBuffer.String()
}
func main() {
var dict MyDictionary = make(MyDictionary)
dict["hello"] = "world"
dict["floating"] = 10.0
dict["whole"] = 12
fmt.Println(dict)
}
输出
2009/11/10 23:00:00 string
2009/11/10 23:00:00 Type was: float64
2009/11/10 23:00:00 Type was: int
hello: floating: whole: