Skip to content

Instantly share code, notes, and snippets.

@patricksuo
Last active August 29, 2015 14:06
Show Gist options
  • Save patricksuo/0ad230d86baceca28387 to your computer and use it in GitHub Desktop.
Save patricksuo/0ad230d86baceca28387 to your computer and use it in GitHub Desktop.
utils
package utils
import (
"fmt"
"reflect"
)
func SmartPrint(data interface{}) {
indent := "\t"
var printer func(reflect.Value, int)
printer = func(val reflect.Value, deep int) {
if deep > 10 {
panic("too deep")
}
for val.Kind() == reflect.Ptr {
val = val.Elem()
}
if val.Kind() != reflect.Struct {
fmt.Println(data)
return
} else {
//TabIn(deep, indent, "{\n")
//defer TabIn(deep, indent, "}\n")
}
typ := val.Type()
fieldNum := val.NumField()
for i := 0; i < fieldNum; i++ {
structField := typ.Field(i)
elem := val.Field(i)
for elem.Kind() == reflect.Ptr {
elem = elem.Elem()
}
if structField.Anonymous {
TabIn(deep+1, indent, "-Anonymous Field : ")
} else {
TabIn(deep+1, indent, structField.Name+" : ")
}
if structField.Tag.Get("field_ignore") == "ignore" {
fmt.Println("<IGNORE>")
continue
}
switch elem.Kind() {
case reflect.Struct:
fmt.Println("{")
printer(elem, deep+1)
TabIn(deep+1, indent, "}\n")
case reflect.Slice, reflect.Array:
fmt.Println("[")
elemLen := elem.Len()
if elemLen > 0 && elem.Index(0).Kind() == reflect.Uint8 && structField.Tag.Get("field_style") == "string" {
if elem.Kind() == reflect.Slice {
TabIn(deep+2, indent, string(elem.Bytes()))
} else if elem.Kind() == reflect.Array {
byteSlice := make([]byte, elemLen, elemLen)
for j := 0; j < elemLen; j++ {
byteSlice[j] = elem.Index(j).Interface().(byte)
}
TabIn(deep+2, indent, "")
fmt.Print(string(byteSlice))
}
fmt.Println()
} else {
//fmt.Print("[DEBUG]", elem.Index(0).Kind(), "[DEBUG]")
for j := 0; j < elemLen; j++ {
printer(elem.Index(j), deep+2)
}
}
TabIn(deep+1, indent, "]\n")
default:
fmt.Println(elem.Interface())
}
}
}
val := reflect.ValueOf(data)
for val.Kind() == reflect.Ptr {
val = val.Elem()
}
if val.Kind() == reflect.Struct {
fmt.Println("{\n")
defer fmt.Println("}\n")
}
printer(val, 0)
}
func TabIn(n int, indent string, val string) {
for i := 0; i < n; i++ {
fmt.Print(indent)
}
fmt.Print(val)
}
package utils
import (
"testing"
)
type Address struct {
Home string
}
type Phone struct {
Number int
}
type User struct {
Name string
Age uint16
Addr *Address
PhoneNum []Phone
}
type Person struct {
Name string
Age int
}
type Facebook struct {
People []Person
}
type Facebook2 struct {
People []*Person
}
func try1() {
address := Address{
Home: "Address",
}
user := User{
Name: "苏沛",
Age: 23,
Addr: &address,
PhoneNum: []Phone{Phone{12345}, Phone{45677}},
//Addr: address,
}
SmartPrint(user)
}
func try2() {
var f Facebook
f.People = append(f.People, Person{Name: "supei",
Age: 23,
})
f.People = append(f.People, Person{Name: "sillyousu",
Age: 24})
SmartPrint(f)
}
func try3() {
var f Facebook2
f.People = append(f.People, &Person{Name: "supei",
Age: 23,
})
f.People = append(f.People, &Person{Name: "sillyousu",
Age: 24})
SmartPrint(f)
}
type SliceOfByte struct {
Content []byte `field_style:"string"`
Title [3]byte `field_style:"string" field_ignore:"ignore"`
}
func try4() {
s := SliceOfByte{
//Content: []byte{'1', '3'},
Content: []byte{'1', '2', '3'},
Title: [3]byte{'a', 'b', 'c'},
}
SmartPrint(s)
}
func TestSmartPrint(t *testing.T) {
try1()
try2()
try3()
try4()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment