github.com/andeya/ameda@v1.5.3/typconv.go (about) 1 package ameda 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 // UnsafeBytesToString convert []byte type to string type. 9 func UnsafeBytesToString(b []byte) string { 10 return *(*string)(unsafe.Pointer(&b)) 11 } 12 13 // UnsafeStringToBytes convert string type to []byte type. 14 // NOTE: 15 // 16 // panic if modify the member value of the []byte. 17 func UnsafeStringToBytes(s string) []byte { 18 return *(*[]byte)(unsafe.Pointer( 19 &struct { 20 string 21 Cap int 22 }{s, len(s)}, 23 )) 24 } 25 26 // IndirectValue gets the indirect value. 27 func IndirectValue(v reflect.Value) reflect.Value { 28 if !v.IsValid() { 29 return v 30 } 31 if v.Kind() != reflect.Ptr { 32 // Avoid creating a reflect.Value if it's not a pointer. 33 return v 34 } 35 for v.Kind() == reflect.Ptr && !v.IsNil() { 36 v = v.Elem() 37 } 38 return v 39 } 40 41 // DereferenceType dereference, get the underlying non-pointer type. 42 func DereferenceType(t reflect.Type) reflect.Type { 43 for t.Kind() == reflect.Ptr { 44 t = t.Elem() 45 } 46 return t 47 } 48 49 // DereferenceValue dereference and unpack interface, 50 // get the underlying non-pointer and non-interface value. 51 func DereferenceValue(v reflect.Value) reflect.Value { 52 for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { 53 v = v.Elem() 54 } 55 return v 56 } 57 58 // DereferencePtrValue returns the underlying non-pointer type value. 59 func DereferencePtrValue(v reflect.Value) reflect.Value { 60 for v.Kind() == reflect.Ptr { 61 v = v.Elem() 62 } 63 return v 64 } 65 66 // DereferenceInterfaceValue returns the value of the underlying type that implements the interface v. 67 func DereferenceInterfaceValue(v reflect.Value) reflect.Value { 68 for v.Kind() == reflect.Interface { 69 v = v.Elem() 70 } 71 return v 72 } 73 74 // DereferenceImplementType returns the underlying type of the value that implements the interface v. 75 func DereferenceImplementType(v reflect.Value) reflect.Type { 76 return DereferenceType(DereferenceInterfaceValue(v).Type()) 77 } 78 79 // DereferenceSlice convert []*T to []T. 80 func DereferenceSlice(v reflect.Value) reflect.Value { 81 m := v.Len() - 1 82 if m < 0 { 83 return reflect.New(reflect.SliceOf(DereferenceType(v.Type().Elem()))).Elem() 84 } 85 s := make([]reflect.Value, m+1) 86 for ; m >= 0; m-- { 87 s[m] = DereferenceValue(v.Index(m)) 88 } 89 v = reflect.New(reflect.SliceOf(s[0].Type())).Elem() 90 v = reflect.Append(v, s...) 91 return v 92 } 93 94 // ReferenceSlice convert []T to []*T, the ptrDepth is the count of '*'. 95 func ReferenceSlice(v reflect.Value, ptrDepth int) reflect.Value { 96 if ptrDepth <= 0 { 97 return v 98 } 99 m := v.Len() - 1 100 if m < 0 { 101 return reflect.New(reflect.SliceOf(ReferenceType(v.Type().Elem(), ptrDepth))).Elem() 102 } 103 s := make([]reflect.Value, m+1) 104 for ; m >= 0; m-- { 105 s[m] = ReferenceValue(v.Index(m), ptrDepth) 106 } 107 v = reflect.New(reflect.SliceOf(s[0].Type())).Elem() 108 v = reflect.Append(v, s...) 109 return v 110 } 111 112 // ReferenceType convert T to *T, the ptrDepth is the count of '*'. 113 func ReferenceType(t reflect.Type, ptrDepth int) reflect.Type { 114 switch { 115 case ptrDepth > 0: 116 for ; ptrDepth > 0; ptrDepth-- { 117 t = reflect.PtrTo(t) 118 } 119 case ptrDepth < 0: 120 for ; ptrDepth < 0 && t.Kind() == reflect.Ptr; ptrDepth++ { 121 t = t.Elem() 122 } 123 } 124 return t 125 } 126 127 // ReferenceValue convert T to *T, the ptrDepth is the count of '*'. 128 func ReferenceValue(v reflect.Value, ptrDepth int) reflect.Value { 129 switch { 130 case ptrDepth > 0: 131 for ; ptrDepth > 0; ptrDepth-- { 132 vv := reflect.New(v.Type()) 133 vv.Elem().Set(v) 134 v = vv 135 } 136 case ptrDepth < 0: 137 for ; ptrDepth < 0 && v.Kind() == reflect.Ptr; ptrDepth++ { 138 v = v.Elem() 139 } 140 } 141 return v 142 }