lazyhandler/util/implements.go
2025-02-22 23:06:16 +08:00

46 lines
1.2 KiB
Go

package util
import (
"reflect"
)
// Implements get reflect.Zero(T) and (o).Implements(T)
func Implements[T any](o any) (T, bool) {
iface := reflect.TypeOf((*T)(nil)).Elem()
reflectType := reflect.TypeOf(o)
if alreadyReflectType, ok := o.(reflect.Type); ok {
reflectType = alreadyReflectType
o = reflect.Zero(reflectType).Interface()
} else if alreadyReflectValue, ok := o.(reflect.Value); ok {
reflectType = alreadyReflectValue.Type()
o = alreadyReflectValue.Interface()
}
if reflectType.Implements(iface) {
if reflectType.Kind() == reflect.Interface {
return *reflect.New(iface).Interface().(*T), true
}
return o.(T), true
} else {
return *reflect.New(iface).Interface().(*T), false
}
}
// PointerImplements get reflect.New(T) and (&o).Implements(T)
func PointerImplements[I any](o any) (reflect.Value, bool) {
iface := reflect.TypeOf((*I)(nil)).Elem()
reflectType := reflect.TypeOf(&o)
if alreadyReflectType, ok := o.(reflect.Type); ok {
reflectType = reflect.PointerTo(alreadyReflectType)
} else if alreadyReflectValue, ok := o.(reflect.Value); ok {
reflectType = reflect.PointerTo(alreadyReflectValue.Type())
}
reflectValue := reflect.New(reflectType.Elem())
return reflectValue, reflectType.Implements(iface)
}