print.go.1 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package typekit
  2. import (
  3. "fmt"
  4. "reflect"
  5. "sort"
  6. "strings"
  7. )
  8. const (
  9. colorReset = "\033[0m"
  10. colorStruct = "\033[34m"
  11. colorField = "\033[32m"
  12. colorMap = "\033[33m"
  13. colorSlice = "\033[35m"
  14. colorValue = "\033[31m"
  15. colorKey = "\033[36m"
  16. )
  17. func PrettyPrint(v interface{}) string {
  18. return prettyPrint(reflect.ValueOf(v), 0, make(map[uintptr]bool)).String()
  19. }
  20. type lines []string
  21. func (l lines) String() string {
  22. return strings.Join(l, "\n")
  23. }
  24. func prettyPrint(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
  25. original := v
  26. // 改进的指针/接口处理逻辑
  27. for {
  28. switch v.Kind() {
  29. case reflect.Ptr:
  30. if v.IsNil() {
  31. return lines{colorValue + "nil" + colorReset}
  32. }
  33. ptr := v.Pointer() // 使用正确获取指针值的方法
  34. if visited[ptr] {
  35. // 正确格式化指针地址
  36. return lines{fmt.Sprintf("%s&%p%s", colorValue, v.Interface(), colorReset)}
  37. }
  38. visited[ptr] = true
  39. original = v
  40. v = v.Elem()
  41. case reflect.Interface:
  42. if v.IsNil() {
  43. return lines{colorValue + "nil" + colorReset}
  44. }
  45. v = v.Elem()
  46. default:
  47. goto END_DEREF
  48. }
  49. }
  50. END_DEREF:
  51. switch v.Kind() {
  52. case reflect.Struct:
  53. return printStruct(v, indentLevel, visited)
  54. case reflect.Map:
  55. return printMap(v, indentLevel, visited)
  56. case reflect.Slice, reflect.Array:
  57. return printSlice(v, indentLevel, visited)
  58. case reflect.String:
  59. return lines{fmt.Sprintf("%s%q%s", colorValue, v.String(), colorReset)}
  60. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  61. return lines{fmt.Sprintf("%s%d%s", colorValue, v.Int(), colorReset)}
  62. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  63. return lines{fmt.Sprintf("%s%d%s", colorValue, v.Uint(), colorReset)}
  64. case reflect.Float32, reflect.Float64:
  65. return lines{fmt.Sprintf("%s%.2f%s", colorValue, v.Float(), colorReset)}
  66. case reflect.Bool:
  67. return lines{fmt.Sprintf("%s%t%s", colorValue, v.Bool(), colorReset)}
  68. default:
  69. if original.Kind() == reflect.Ptr {
  70. return lines{fmt.Sprintf("%s%v%s", colorValue, original.Interface(), colorReset)}
  71. }
  72. return lines{fmt.Sprintf("%s%v%s", colorValue, v.Interface(), colorReset)}
  73. }
  74. }
  75. // 完整实现结构体打印
  76. func printStruct(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
  77. header := fmt.Sprintf("%s%s%s%s:",
  78. strings.Repeat(" ", indentLevel),
  79. colorStruct,
  80. v.Type().String(),
  81. colorReset,
  82. )
  83. result := lines{header}
  84. for i := 0; i < v.NumField(); i++ {
  85. field := v.Type().Field(i)
  86. fieldValue := v.Field(i)
  87. fieldLines := prettyPrint(fieldValue, indentLevel+1, visited)
  88. fieldHeader := fmt.Sprintf("%s%s%s: ",
  89. strings.Repeat(" ", indentLevel+1),
  90. colorField,
  91. field.Name,
  92. )
  93. if len(fieldLines) == 0 {
  94. result = append(result, fieldHeader+colorValue+"<invalid>"+colorReset)
  95. continue
  96. }
  97. result = append(result, fieldHeader+fieldLines[0])
  98. for _, line := range fieldLines[1:] {
  99. result = append(result,
  100. strings.Repeat(" ", indentLevel+1)+" "+line)
  101. }
  102. }
  103. return result
  104. }
  105. // 完整实现map打印
  106. func printMap(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
  107. header := fmt.Sprintf("%s%s%s%s:",
  108. strings.Repeat(" ", indentLevel),
  109. colorMap,
  110. v.Type().String(),
  111. colorReset,
  112. )
  113. result := lines{header}
  114. keys := v.MapKeys()
  115. sort.Slice(keys, func(i, j int) bool {
  116. return fmt.Sprintf("%v", keys[i]) < fmt.Sprintf("%v", keys[j])
  117. })
  118. for _, key := range keys {
  119. keyLines := prettyPrint(key, 0, visited)
  120. valueLines := prettyPrint(v.MapIndex(key), indentLevel+1, visited)
  121. keyHeader := fmt.Sprintf("%s%s%s: ",
  122. strings.Repeat(" ", indentLevel+1),
  123. colorKey,
  124. strings.Join(keyLines, ""),
  125. )
  126. if len(valueLines) == 0 {
  127. result = append(result, keyHeader+colorValue+"<invalid>"+colorReset)
  128. continue
  129. }
  130. result = append(result, keyHeader+valueLines[0])
  131. for _, line := range valueLines[1:] {
  132. result = append(result,
  133. strings.Repeat(" ", indentLevel+1)+" "+line)
  134. }
  135. }
  136. return result
  137. }
  138. // 完整实现slice/array打印
  139. func printSlice(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines {
  140. header := fmt.Sprintf("%s%s%s%s:",
  141. strings.Repeat(" ", indentLevel),
  142. colorSlice,
  143. v.Type().String(),
  144. colorReset,
  145. )
  146. result := lines{header}
  147. for i := 0; i < v.Len(); i++ {
  148. elemLines := prettyPrint(v.Index(i), indentLevel+1, visited)
  149. bullet := fmt.Sprintf("%s- ",
  150. strings.Repeat(" ", indentLevel+1),
  151. )
  152. if len(elemLines) == 0 {
  153. result = append(result, bullet+colorValue+"<invalid>"+colorReset)
  154. continue
  155. }
  156. result = append(result, bullet+elemLines[0])
  157. for _, line := range elemLines[1:] {
  158. result = append(result,
  159. strings.Repeat(" ", indentLevel+1)+" "+line)
  160. }
  161. }
  162. return result
  163. }
  164. /*
  165. // 修正后的测试用例
  166. type Person struct {
  167. Name string
  168. Age int
  169. Hobbies []string
  170. Address struct {
  171. City string
  172. State string
  173. }
  174. Metadata map[string]interface{}
  175. }
  176. func main() {
  177. p := Person{
  178. Name: "Alice",
  179. Age: 30,
  180. Hobbies: []string{"Reading", "Hiking"},
  181. Metadata: map[string]interface{}{
  182. "id": 123,
  183. "scores": []float64{98.5, 87.2},
  184. "nested": map[string]interface{}{"a": 1, "b": 2},
  185. },
  186. }
  187. p.Address.City = "New York"
  188. p.Address.State = "NY"
  189. p.Metadata["self_ref"] = &p // 正确设置循环引用
  190. fmt.Println(PrettyPrint(p))
  191. }
  192. */