package lxUtil import ( "reflect" "strings" ) // IsZeroOfUnderlyingType 判断是否零值对象, 考虑到了model是指针的情况 func IsZeroOfUnderlyingType(model interface{}) bool { // ref: https://www.coder.work/article/200965 rawType := reflect.TypeOf(model) if rawType.Kind() == reflect.Ptr { // 指针 rawType = rawType.Elem() return reflect.DeepEqual(model, reflect.New(rawType).Interface()) } return reflect.DeepEqual(model, reflect.Zero(rawType).Interface()) } // ToSlice 为什么不能被 cast.ToSlice 替代? func ToSlice1(v interface{}) []interface{} { var out []interface{} rv := reflect.ValueOf(v) if rv.Kind() == reflect.Slice { for i := 0; i < rv.Len(); i++ { out = append(out, rv.Index(i).Interface()) } } else { out = append(out, v) } return out } // FieldToColumn inAmt -> in_amt 结构体属性转成库表字段 func FieldToColumn(s string) string { return CamelCaseToSnakeCase(s) } // CamelCaseToSnakeCase 小驼峰转下划线 // mesLine -> mes_line // mesLine-lineCode-lineDesc -> mes_line-line_code-line_desc func CamelCaseToSnakeCase(s string) string { if s = strings.TrimSpace(s); s == "" { return "" } var ( buf strings.Builder prevUpper, nextUpper, nextNumber bool curUpper = s[0] <= 'Z' && s[0] >= 'A' ) for i, r := range s[:len(s)-1] { nextUpper = 'A' <= s[i+1] && s[i+1] <= 'Z' nextNumber = '0' <= s[i+1] && s[i+1] <= '9' if curUpper { if prevUpper && (nextUpper || nextNumber) { buf.WriteRune(r + 32) } else { if i > 0 && s[i-1] != '_' && s[i+1] != '_' { buf.WriteByte('_') } buf.WriteRune(r + 32) } } else { buf.WriteRune(r) } prevUpper = curUpper curUpper = nextUpper } if curUpper { if !prevUpper && len(s) > 1 { buf.WriteByte('_') } buf.WriteByte(s[len(s)-1] + 32) } else { buf.WriteByte(s[len(s)-1]) } return buf.String() }