1 Star 0 Fork 0

zhenyangze / zlib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
function.go 5.06 KB
一键复制 编辑 原始数据 按行查看 历史
zhenyangze 提交于 2022-10-04 23:27 . master: [feature] update package
package zlib
import (
"errors"
"fmt"
"reflect"
"strings"
"unicode"
)
// reflectFinalValue 获取反射的最终值.
func reflectFinalValue(r reflect.Value) (reflect.Value, bool) {
var isPtr bool
// 如果是指针,则获取其所指向的元素
if r.Kind() == reflect.Ptr {
r = r.Elem()
isPtr = true
}
return r, isPtr
}
// reflectFinalType 获取反射的最终类型.
func reflectFinalType(r reflect.Type) (reflect.Type, bool) {
var isPtr bool
// 如果是指针,则获取其所指向的元素
if r.Kind() == reflect.Ptr {
r = r.Elem()
isPtr = true
}
return r, isPtr
}
// reflectTypesMap 递归获取反射字段类型Map.
func reflectTypesMap(r reflect.Type, res map[string]reflect.Type) {
for i := 0; i < r.NumField(); i++ {
field := r.Field(i)
if field.Anonymous { //匿名字段
subTyp := r.Field(i).Type
reflectTypesMap(subTyp, res)
} else if field.PkgPath == "" { //公开字段
res[field.Name] = field.Type
}
}
}
// reflect2Itf 将反射值转为接口(原值)
func reflect2Itf(r reflect.Value) (res interface{}) {
switch r.Kind() {
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
res = r.Int()
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
res = r.Uint()
case reflect.Float32, reflect.Float64:
res = r.Float()
case reflect.String:
res = r.String()
case reflect.Bool:
res = r.Bool()
default:
if r.CanInterface() {
res = r.Interface()
} else {
res = r
}
}
return
}
// structVal 获取结构体的反射值.
func structVal(obj interface{}) (reflect.Value, error) {
v := reflect.ValueOf(obj)
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct {
return v, errors.New("[structVal]`obj type must be struct; but : " + v.Kind().String())
}
return v, nil
}
// structFields 获取结构体的字段切片;all是否包含所有字段(包括未导出的).
func structFields(obj interface{}, all bool) ([]reflect.StructField, error) {
v, e := structVal(obj)
if e != nil {
return nil, e
}
var fs []reflect.StructField
var t = v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
// 不能访问未导出的字段
if !all && field.PkgPath != "" {
continue
}
fs = append(fs, field)
}
return fs, nil
}
// compareConditionMap 比对数组是否匹配条件.condition为条件字典,arr为要比对的数据(字典/结构体).
func compareConditionMap(condition map[string]interface{}, arr interface{}) (res interface{}) {
val := reflect.ValueOf(arr)
conNum := len(condition)
if conNum > 0 {
chkNum := 0
switch val.Kind() {
case reflect.Map:
if conNum > 0 {
for _, k := range val.MapKeys() {
if condVal, ok := condition[k.String()]; ok && reflect.DeepEqual(val.MapIndex(k).Interface(), condVal) {
chkNum++
}
}
}
case reflect.Struct:
var field reflect.Value
for k, v := range condition {
field = val.FieldByName(k)
if field.IsValid() && field.CanInterface() && reflect.DeepEqual(field.Interface(), v) {
chkNum++
}
}
default:
panic("[compareConditionMap]`arr type must be map|struct; but : " + val.Kind().String())
}
if chkNum == conNum {
res = arr
}
}
return
}
// getTrimMask 获取要修剪的字符串集合,masks为要屏蔽的字符切片.
func getTrimMask(masks []string) string {
var str string
if len(masks) == 0 {
str = blankChars
} else {
str = strings.Join(masks, "")
}
return str
}
// GetFieldValue 获取(字典/结构体的)字段值;fieldName为字段名,大小写敏感.
func GetFieldValue(arr interface{}, fieldName string) (res interface{}, err error) {
val := reflect.ValueOf(arr)
switch val.Kind() {
case reflect.Map:
for _, subKey := range val.MapKeys() {
if fmt.Sprintf("%s", subKey) == fieldName {
res = val.MapIndex(subKey).Interface()
break
}
}
case reflect.Struct:
field := val.FieldByName(fieldName)
if !field.IsValid() || !field.CanInterface() {
break
}
res = field.Interface()
default:
err = errors.New("[GetFieldValue]`arr type must be map|struct; but : " + val.Kind().String())
}
return
}
// isCaseConnector 是否字符转换连接符.
func isCaseConnector(r rune) bool {
return r == '-' || r == '_' || unicode.IsSpace(r)
}
func invokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
fv := functionValue(fn)
params := make([]reflect.Value, len(args))
for i, item := range args {
params[i] = reflect.ValueOf(item)
}
return fv.Call(params)
}
func unsafeInvokeFunc(fn interface{}, args ...interface{}) []reflect.Value {
fv := reflect.ValueOf(fn)
params := make([]reflect.Value, len(args))
for i, item := range args {
params[i] = reflect.ValueOf(item)
}
return fv.Call(params)
}
func functionValue(function interface{}) reflect.Value {
v := reflect.ValueOf(function)
if v.Kind() != reflect.Func {
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
}
return v
}
func mustBeFunction(function interface{}) {
v := reflect.ValueOf(function)
if v.Kind() != reflect.Func {
panic(fmt.Sprintf("Invalid function type, value of type %T", function))
}
}
1
https://gitee.com/zhenyangze/zlib.git
git@gitee.com:zhenyangze/zlib.git
zhenyangze
zlib
zlib
v1.0.2

搜索帮助