package typekit import ( "fmt" "reflect" "sort" "strings" ) const ( colorReset = "\033[0m" colorStruct = "\033[34m" colorField = "\033[32m" colorMap = "\033[33m" colorSlice = "\033[35m" colorValue = "\033[31m" colorKey = "\033[36m" ) func PrettyPrint(v interface{}) string { return prettyPrint(reflect.ValueOf(v), 0, make(map[uintptr]bool)).String() } type lines []string func (l lines) String() string { return strings.Join(l, "\n") } func prettyPrint(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines { original := v // 改进的指针/接口处理逻辑 for { switch v.Kind() { case reflect.Ptr: if v.IsNil() { return lines{colorValue + "nil" + colorReset} } ptr := v.Pointer() // 使用正确获取指针值的方法 if visited[ptr] { // 正确格式化指针地址 return lines{fmt.Sprintf("%s&%p%s", colorValue, v.Interface(), colorReset)} } visited[ptr] = true original = v v = v.Elem() case reflect.Interface: if v.IsNil() { return lines{colorValue + "nil" + colorReset} } v = v.Elem() default: goto END_DEREF } } END_DEREF: switch v.Kind() { case reflect.Struct: return printStruct(v, indentLevel, visited) case reflect.Map: return printMap(v, indentLevel, visited) case reflect.Slice, reflect.Array: return printSlice(v, indentLevel, visited) case reflect.String: return lines{fmt.Sprintf("%s%q%s", colorValue, v.String(), colorReset)} case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return lines{fmt.Sprintf("%s%d%s", colorValue, v.Int(), colorReset)} case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return lines{fmt.Sprintf("%s%d%s", colorValue, v.Uint(), colorReset)} case reflect.Float32, reflect.Float64: return lines{fmt.Sprintf("%s%.2f%s", colorValue, v.Float(), colorReset)} case reflect.Bool: return lines{fmt.Sprintf("%s%t%s", colorValue, v.Bool(), colorReset)} default: if original.Kind() == reflect.Ptr { return lines{fmt.Sprintf("%s%v%s", colorValue, original.Interface(), colorReset)} } return lines{fmt.Sprintf("%s%v%s", colorValue, v.Interface(), colorReset)} } } // 完整实现结构体打印 func printStruct(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines { header := fmt.Sprintf("%s%s%s%s:", strings.Repeat(" ", indentLevel), colorStruct, v.Type().String(), colorReset, ) result := lines{header} for i := 0; i < v.NumField(); i++ { field := v.Type().Field(i) fieldValue := v.Field(i) fieldLines := prettyPrint(fieldValue, indentLevel+1, visited) fieldHeader := fmt.Sprintf("%s%s%s: ", strings.Repeat(" ", indentLevel+1), colorField, field.Name, ) if len(fieldLines) == 0 { result = append(result, fieldHeader+colorValue+""+colorReset) continue } result = append(result, fieldHeader+fieldLines[0]) for _, line := range fieldLines[1:] { result = append(result, strings.Repeat(" ", indentLevel+1)+" "+line) } } return result } // 完整实现map打印 func printMap(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines { header := fmt.Sprintf("%s%s%s%s:", strings.Repeat(" ", indentLevel), colorMap, v.Type().String(), colorReset, ) result := lines{header} keys := v.MapKeys() sort.Slice(keys, func(i, j int) bool { return fmt.Sprintf("%v", keys[i]) < fmt.Sprintf("%v", keys[j]) }) for _, key := range keys { keyLines := prettyPrint(key, 0, visited) valueLines := prettyPrint(v.MapIndex(key), indentLevel+1, visited) keyHeader := fmt.Sprintf("%s%s%s: ", strings.Repeat(" ", indentLevel+1), colorKey, strings.Join(keyLines, ""), ) if len(valueLines) == 0 { result = append(result, keyHeader+colorValue+""+colorReset) continue } result = append(result, keyHeader+valueLines[0]) for _, line := range valueLines[1:] { result = append(result, strings.Repeat(" ", indentLevel+1)+" "+line) } } return result } // 完整实现slice/array打印 func printSlice(v reflect.Value, indentLevel int, visited map[uintptr]bool) lines { header := fmt.Sprintf("%s%s%s%s:", strings.Repeat(" ", indentLevel), colorSlice, v.Type().String(), colorReset, ) result := lines{header} for i := 0; i < v.Len(); i++ { elemLines := prettyPrint(v.Index(i), indentLevel+1, visited) bullet := fmt.Sprintf("%s- ", strings.Repeat(" ", indentLevel+1), ) if len(elemLines) == 0 { result = append(result, bullet+colorValue+""+colorReset) continue } result = append(result, bullet+elemLines[0]) for _, line := range elemLines[1:] { result = append(result, strings.Repeat(" ", indentLevel+1)+" "+line) } } return result } /* // 修正后的测试用例 type Person struct { Name string Age int Hobbies []string Address struct { City string State string } Metadata map[string]interface{} } func main() { p := Person{ Name: "Alice", Age: 30, Hobbies: []string{"Reading", "Hiking"}, Metadata: map[string]interface{}{ "id": 123, "scores": []float64{98.5, 87.2}, "nested": map[string]interface{}{"a": 1, "b": 2}, }, } p.Address.City = "New York" p.Address.State = "NY" p.Metadata["self_ref"] = &p // 正确设置循环引用 fmt.Println(PrettyPrint(p)) } */