打印带有类型的接口映射。

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

Print interface map with types

问题

我有一个函数,它接收一些字节并将它们解析成一个映射。我想打印出这个映射,如果可能的话,还要包含类型信息。我尝试了以下代码:

  1. package main
  2. import "fmt"
  3. func main() {
  4. m := map[string]interface{}{
  5. "one": uint16(1), "two": map[string]interface{}{
  6. "three": uint32(3), "four": uint64(4),
  7. },
  8. }
  9. /*
  10. map[string]interface {}{
  11. "one":0x1, "two":map[string]interface {}{"four":0x4, "three":0x3}
  12. }
  13. */
  14. fmt.Printf("%#v\n", m)
  15. }

但它没有打印出数字类型。我可以这样做:

  1. // uint16
  2. fmt.Printf("%T\n", m["one"])

但是映射可能很大,所以我想避免手动打印每个值。我想知道是否有可能实现我想要的效果?

英文:

I have a function that takes in some bytes, and parses them into a map. I would
like to print out this map, but with the types included if possible. I tried
this:

  1. package main
  2. import "fmt"
  3. func main() {
  4. m := map[string]interface{}{
  5. "one": uint16(1), "two": map[string]interface{}{
  6. "three": uint32(3), "four": uint64(4),
  7. },
  8. }
  9. /*
  10. map[string]interface {}{
  11. "one":0x1, "two":map[string]interface {}{"four":0x4, "three":0x3}
  12. }
  13. */
  14. fmt.Printf("%#v\n", m)
  15. }

but it doesnt print out the number types. I can do this:

  1. // uint16
  2. fmt.Printf("%T\n", m["one"])

but the map can be pretty big, so I would like to avoid having to manually print
every value. Is it possible to do what I am wanting?

答案1

得分: 3

使用for循环和递归打印地图值的类型:

  1. func printTypes(m map[string]interface{}, indent string) {
  2. for k, v := range m {
  3. fmt.Printf("%s%s: %T\n", indent, k, v)
  4. // 如果值是嵌套地图,则递归调用
  5. if m, ok := v.(map[string]interface{}); ok {
  6. printTypes(m, indent+" ")
  7. }
  8. }
  9. }
  10. // 调用方式如下:
  11. printTypes(m, "")

这段代码的作用是遍历一个地图(map)的键值对,并打印出每个值的类型。如果值是一个嵌套的地图,则会递归调用函数来打印嵌套地图中的值类型。

英文:

Use for loops and recursion to print map values types:

  1. func printTypes(m map[string]interface{}, indent string) {
  2. for k, v := range m {
  3. fmt.Printf("%s%s: %T\n", indent, k, v)
  4. // Recurse if value is a nested map
  5. if m, ok := v.(map[string]interface{}); ok {
  6. printTypes(m, indent+" ")
  7. }
  8. }
  9. }

Call it like this:

  1. printTypes(m, "")

答案2

得分: 1

如果你能控制地图的创建,你可以使用自定义类型代替:

  1. package object
  2. import "fmt"
  3. type (
  4. Uint16 uint16
  5. Uint32 uint32
  6. Uint64 uint64
  7. )
  8. func (u Uint16) GoString() string {
  9. return fmt.Sprintf("uint16(%v)", uint16(u))
  10. }
  11. func (u Uint32) GoString() string {
  12. return fmt.Sprintf("uint32(%v)", uint32(u))
  13. }
  14. func (u Uint64) GoString() string {
  15. return fmt.Sprintf("uint64(%v)", uint64(u))
  16. }

或者,你可以覆盖整个地图:

  1. package object
  2. import "fmt"
  3. type object map[string]interface{}
  4. func (o object) GoString() string {
  5. str := "map[string]interface{}{"
  6. first := true
  7. for key, val := range o {
  8. if first {
  9. first = false
  10. } else {
  11. str += ","
  12. }
  13. str += fmt.Sprintf("%q:", key)
  14. switch typ := val.(type) {
  15. case uint16:
  16. str += fmt.Sprintf("uint16(%v)", typ)
  17. case uint32:
  18. str += fmt.Sprintf("uint32(%v)", typ)
  19. case uint64:
  20. str += fmt.Sprintf("uint64(%v)", typ)
  21. default:
  22. str += fmt.Sprintf("%#v", val)
  23. }
  24. }
  25. return str + "}"
  26. }

https://godocs.io/fmt#GoStringer

英文:

If you are able to control the creation of the map, you can use custom types
instead:

  1. package object
  2. import "fmt"
  3. type (
  4. Uint16 uint16
  5. Uint32 uint32
  6. Uint64 uint64
  7. )
  8. func (u Uint16) GoString() string {
  9. return fmt.Sprintf("uint16(%v)", uint16(u))
  10. }
  11. func (u Uint32) GoString() string {
  12. return fmt.Sprintf("uint32(%v)", uint32(u))
  13. }
  14. func (u Uint64) GoString() string {
  15. return fmt.Sprintf("uint64(%v)", uint64(u))
  16. }

Or, you can override the whole map:

  1. package object
  2. import "fmt"
  3. type object map[string]interface{}
  4. func (o object) GoString() string {
  5. str := "map[string]interface{}{"
  6. first := true
  7. for key, val := range o {
  8. if first {
  9. first = false
  10. } else {
  11. str += ","
  12. }
  13. str += fmt.Sprintf("%q:", key)
  14. switch typ := val.(type) {
  15. case uint16:
  16. str += fmt.Sprintf("uint16(%v)", typ)
  17. case uint32:
  18. str += fmt.Sprintf("uint32(%v)", typ)
  19. case uint64:
  20. str += fmt.Sprintf("uint64(%v)", typ)
  21. default:
  22. str += fmt.Sprintf("%#v", val)
  23. }
  24. }
  25. return str + "}"
  26. }

https://godocs.io/fmt#GoStringer

huangapple
  • 本文由 发表于 2021年12月1日 05:11:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/70176114.html
匿名

发表评论

匿名网友

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

确定