您的位置 首页 golang

Go开发中结构体 model、dto 、time格式问题


1、背景

model层不允许申明json tag, dto层又重复造轮子,一个表的字段可能20个左右,那么赋值语句难受死了。

其次就是json直接解析,model层的time.Time,完蛋格式不对,返回的数据不对。

比如

{    "user_name": "xiaoli",    "create_time": "2020-06-05T13:53:06.293614+08:00"}复制代码

这种情况,无法解决,就需要必须重写一个dto。

那么如何解决这个问题呢,本人思考了一段时间,最终使用Map来解决。

2、解决问题

1、反射

那么反射会遇到,各种奇葩的书写方式,有些人什么都出传入指针,有些人各种interface{} 隐藏转换,反正就是太过于差异化。

所以就是需要解决,如何准确的拿到Value对象,下面是我写的一个工具类

func GetRealValue(value reflect.Value) reflect.Value {kind := value.Kind()if kind == reflect.Ptr {return GetRealValue(value.Elem())}if kind == reflect.Interface {// eg:var s2 interface{}//s2 = User{}//fmt.Println(reflect.ValueOf(&s2).Elem().Kind())// interface// 所以这里需要将它转换if value.CanInterface() {return GetRealValue(reflect.ValueOf(value.Interface()))}return GetRealValue(value.Elem())}return value}复制代码

解决这个问题,开干

2、下划线命名法

下划线如何解决,结构体的字段属于驼峰命名法,怎么解决呢,为此。

写了一个简单的工具类

问题:1、如果是ID,连续大写,输出i_d

2、因为数组到切片需要拷贝一次,所以可以利用unsafe解决,因为字符串底层就是切片,但是不安全

func CamelCase(s string) string {if s == "" {return ""}t := make([]byte, 0, 32)i := 0for ; i < len(s); i++ {c := s[i]if isASCIIDigit(c) {t = append(t, c)continue}if isASCIIUpper(c) {c ^= ' '}t = append(t, c)for i+1 < len(s) && isASCIIUpper(s[i+1]) {i++t = append(t, '_', s[i]+32)}}//return *(*string)(unsafe.Pointer(&t))return string(t)}func isASCIIUpper(c byte) bool {return 'A' <= c && c <= 'Z'}func isASCIIDigit(c byte) bool {return '0' <= c && c <= '9'}复制代码

3、开干

1、解决time的问题

2、反射、下划线命名法

func ToStdMap(bean interface{}) map[string]interface{} {_value := GetRealValue(reflect.ValueOf(bean))if _value.Kind() != reflect.Struct {panic("the bean mush struct")}_type := _value.Type()fieldNum := _value.NumField()_map := make(map[string]interface{}, fieldNum)for x := 0; x < fieldNum; x++ {field := _type.Field(x)value := GetRealValue(_value.Field(x))if value.CanInterface() {realValue := value.Interface()switch realValue.(type) {case time.Time:_map[CamelCase(field.Name)] = times.FormatStdTime(realValue.(time.Time))default:_map[CamelCase(field.Name)] = realValue}}}return _map}复制代码

4、测试

func TestObjToMap(t *testing.T) {users := Users{UserName: "xiaoli",}now := time.Now()users.CreateTime = &nowstdMap := ToStdMap(users)bytes, err := json.Marshal(stdMap)if err != nil {t.Fatal(err)}fmt.Printf("%s\n", bytes)}复制代码

输出结果:

完美,美中不足是需要使用likedMap,由于Golang源码包没有,所以?,注定乱序

{"create_time":"2020-06-05 14:05:31","user_name":"xiaoli"}复制代码

文章来源:智云一二三科技

文章标题:Go开发中结构体 model、dto 、time格式问题

文章地址:https://www.zhihuclub.com/4498.shtml

关于作者: 智云科技

热门文章

网站地图