gf/internal/reflection/reflection.go
2022-03-11 10:24:42 +08:00

95 lines
2.6 KiB
Go

// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
// Package reflection provides some reflection functions for internal usage.
package reflection
import (
"reflect"
)
type OriginValueAndKindOutput struct {
InputValue reflect.Value
InputKind reflect.Kind
OriginValue reflect.Value
OriginKind reflect.Kind
}
// OriginValueAndKind retrieves and returns the original reflect value and kind.
func OriginValueAndKind(value interface{}) (out OriginValueAndKindOutput) {
if v, ok := value.(reflect.Value); ok {
out.InputValue = v
} else {
out.InputValue = reflect.ValueOf(value)
}
out.InputKind = out.InputValue.Kind()
out.OriginValue = out.InputValue
out.OriginKind = out.InputKind
for out.OriginKind == reflect.Ptr {
out.OriginValue = out.OriginValue.Elem()
out.OriginKind = out.OriginValue.Kind()
}
return
}
type OriginTypeAndKindOutput struct {
InputType reflect.Type
InputKind reflect.Kind
OriginType reflect.Type
OriginKind reflect.Kind
}
// OriginTypeAndKind retrieves and returns the original reflect type and kind.
func OriginTypeAndKind(value interface{}) (out OriginTypeAndKindOutput) {
if value == nil {
return
}
if reflectType, ok := value.(reflect.Type); ok {
out.InputType = reflectType
} else {
if reflectValue, ok := value.(reflect.Value); ok {
out.InputType = reflectValue.Type()
} else {
out.InputType = reflect.TypeOf(value)
}
}
out.InputKind = out.InputType.Kind()
out.OriginType = out.InputType
out.OriginKind = out.InputKind
for out.OriginKind == reflect.Ptr {
out.OriginType = out.OriginType.Elem()
out.OriginKind = out.OriginType.Kind()
}
return
}
// ValueToInterface converts reflect value to its interface type.
func ValueToInterface(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 ValueToInterface(v.Elem())
case reflect.Interface:
return ValueToInterface(v.Elem())
default:
return nil, false
}
}