diff --git a/convertor/convertor.go b/convertor/convertor.go index 56f6280..ce6cb3f 100644 --- a/convertor/convertor.go +++ b/convertor/convertor.go @@ -347,3 +347,31 @@ func CopyProperties[T, U any](dst T, src U) error { return nil } + +// ToInterface converts reflect value to its interface type. +// Play: todo +func ToInterface(v reflect.Value) (value interface{}, ok bool) { + if v.IsValid() && v.CanInterface() { + return v.Interface(), true + } + switch v.Kind() { + case reflect.Bool: + return v.Bool(), true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int(), true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint(), true + case reflect.Float32, reflect.Float64: + return v.Float(), true + case reflect.Complex64, reflect.Complex128: + return v.Complex(), true + case reflect.String: + return v.String(), true + case reflect.Ptr: + return ToInterface(v.Elem()) + case reflect.Interface: + return ToInterface(v.Elem()) + default: + return nil, false + } +} diff --git a/convertor/convertor_example_test.go b/convertor/convertor_example_test.go index 0caa26a..6990b2c 100644 --- a/convertor/convertor_example_test.go +++ b/convertor/convertor_example_test.go @@ -2,6 +2,7 @@ package convertor import ( "fmt" + "reflect" "strconv" ) @@ -349,3 +350,17 @@ func ExampleCopyProperties() { // 127.0.0.1 // 3 } + +func ExampleToInterface() { + val := reflect.ValueOf("abc") + iVal, ok := ToInterface(val) + + fmt.Printf("%T\n", iVal) + fmt.Printf("%v\n", iVal) + fmt.Println(ok) + + // Output: + // string + // abc + // true +} diff --git a/convertor/convertor_test.go b/convertor/convertor_test.go index ba206a6..0f97b31 100644 --- a/convertor/convertor_test.go +++ b/convertor/convertor_test.go @@ -367,3 +367,32 @@ func TestCopyProperties(t *testing.T) { assert.Equal("127.0.0.1", indicatorVO.Ip) assert.Equal(3, len(indicatorVO.Disk)) } + +func TestToInterface(t *testing.T) { + assert := internal.NewAssert(t, "TestToInterface") + + cases := []reflect.Value{ + reflect.ValueOf("abc"), + reflect.ValueOf(int(0)), reflect.ValueOf(int8(1)), reflect.ValueOf(int16(-1)), reflect.ValueOf(int32(123)), reflect.ValueOf(int64(123)), + reflect.ValueOf(uint(123)), reflect.ValueOf(uint8(123)), reflect.ValueOf(uint16(123)), reflect.ValueOf(uint32(123)), reflect.ValueOf(uint64(123)), + reflect.ValueOf(float64(12.3)), reflect.ValueOf(float32(12.3)), + reflect.ValueOf(true), reflect.ValueOf(false), + } + + expected := []interface{}{ + "abc", + 0, int8(1), int16(-1), int32(123), int64(123), + uint(123), uint8(123), uint16(123), uint32(123), uint64(123), + float64(12.3), float32(12.3), + true, false, + } + + for i := 0; i < len(cases); i++ { + actual, _ := ToInterface(cases[i]) + assert.Equal(expected[i], actual) + } + + nilVal, ok := ToInterface(reflect.ValueOf(nil)) + assert.EqualValues(nil, nilVal) + assert.Equal(false, ok) +}