脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - Go开发中结构体 model、dto 、time格式问题

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

2021-12-21 23:08Anthony-Dong Golang

model层不允许使用 json, dto层又重复造轮子,一个表的字段可能20个左右,那么赋值语句难受死了。其次就是json直接解析,model层的time.Time,完蛋格式不对,返回的数据不对。

1、背景

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

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

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

比如

  1.     "user_name""xiaoli"
  2.     "create_time""2020-06-05T13:53:06.293614+08:00" 

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

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

2、解决问题

1、反射

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

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

  1. func GetRealValue(value reflect.Value) reflect.Value { 
  2.     kind := value.Kind() 
  3.     if kind == reflect.Ptr { 
  4.         return GetRealValue(value.Elem()) 
  5.     } 
  6.     if kind == reflect.Interface { 
  7.         // eg:var s2 interface{} 
  8.         //  s2 = User{} 
  9.         //  fmt.Println(reflect.ValueOf(&s2).Elem().Kind())// interface 
  10.         // 所以这里需要将它转换 
  11.         if value.CanInterface() { 
  12.             return GetRealValue(reflect.ValueOf(value.Interface())) 
  13.         } 
  14.         return GetRealValue(value.Elem()) 
  15.     } 
  16.     return value 

解决这个问题,开干

2、下划线命名法

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

写了一个简单的工具类

问题:

  • 如果是ID,连续大写,输出i_d
  • 因为数组到切片需要拷贝一次,所以可以利用unsafe解决,因为字符串底层就是切片,但是不安全
  1. func CamelCase(s string) string { 
  2.     if s == "" { 
  3.         return "" 
  4.     } 
  5.     t := make([]byte, 0, 32) 
  6.     i := 0 
  7.     for ; i < len(s); i++ { 
  8.         c := s[i] 
  9.         if isASCIIDigit(c) { 
  10.             t = append(t, c) 
  11.             continue 
  12.         } 
  13.         if isASCIIUpper(c) { 
  14.             c ^= ' ' 
  15.         } 
  16.         t = append(t, c) 
  17.         for i+1 < len(s) && isASCIIUpper(s[i+1]) { 
  18.             i++ 
  19.             t = append(t, '_', s[i]+32) 
  20.         } 
  21.     } 
  22.     //return *(*string)(unsafe.Pointer(&t)) 
  23.     return string(t) 
  24. func isASCIIUpper(c byte) bool { 
  25.     return 'A' <= c && c <= 'Z' 
  26.  
  27. func isASCIIDigit(c byte) bool { 
  28.     return '0' <= c && c <= '9' 

3、开干

  • 解决time的问题
  • 反射、下划线命名法
  1. func ToStdMap(bean interface{}) map[string]interface{} { 
  2.     _value := GetRealValue(reflect.ValueOf(bean)) 
  3.     if _value.Kind() != reflect.Struct { 
  4.         panic("the bean mush struct"
  5.     } 
  6.     _type := _value.Type() 
  7.     fieldNum := _value.NumField() 
  8.     _map := make(map[string]interface{}, fieldNum) 
  9.     for x := 0; x < fieldNum; x++ { 
  10.         field := _type.Field(x) 
  11.         value := GetRealValue(_value.Field(x)) 
  12.         if value.CanInterface() { 
  13.             realValue := value.Interface() 
  14.             switch realValue.(type) { 
  15.             case time.Time
  16.                 _map[CamelCase(field.Name)] = times.FormatStdTime(realValue.(time.Time)) 
  17.             default
  18.                 _map[CamelCase(field.Name)] = realValue 
  19.             } 
  20.         } 
  21.     } 
  22.     return _map 

4、测试

  1. func TestObjToMap(t *testing.T) { 
  2.     users := Users{ 
  3.         UserName: "xiaoli"
  4.     } 
  5.     now := time.Now() 
  6.     users.CreateTime = &now 
  7.     stdMap := ToStdMap(users) 
  8.     bytes, err := json.Marshal(stdMap) 
  9.     if err != nil { 
  10.         t.Fatal(err) 
  11.     } 
  12.     fmt.Printf("%s\n", bytes) 

输出结果:

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

  1. {"create_time":"2020-06-05 14:05:31","user_name":"xiaoli"

原文地址:https://www.toutiao.com/a7043692493984039462/

延伸 · 阅读

精彩推荐
  • Golanggo日志系统logrus显示文件和行号的操作

    go日志系统logrus显示文件和行号的操作

    这篇文章主要介绍了go日志系统logrus显示文件和行号的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    SmallQinYan12302021-02-02
  • GolangGolang通脉之数据类型详情

    Golang通脉之数据类型详情

    这篇文章主要介绍了Golang通脉之数据类型,在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等,Go语言中标识符允许由...

    4272021-11-24
  • Golanggolang的httpserver优雅重启方法详解

    golang的httpserver优雅重启方法详解

    这篇文章主要给大家介绍了关于golang的httpserver优雅重启的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    helight2992020-05-14
  • Golanggolang json.Marshal 特殊html字符被转义的解决方法

    golang json.Marshal 特殊html字符被转义的解决方法

    今天小编就为大家分享一篇golang json.Marshal 特殊html字符被转义的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    李浩的life12792020-05-27
  • Golanggolang如何使用struct的tag属性的详细介绍

    golang如何使用struct的tag属性的详细介绍

    这篇文章主要介绍了golang如何使用struct的tag属性的详细介绍,从例子说起,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看...

    Go语言中文网11352020-05-21
  • Golanggo语言制作端口扫描器

    go语言制作端口扫描器

    本文给大家分享的是使用go语言编写的TCP端口扫描器,可以选择IP范围,扫描的端口,以及多线程,有需要的小伙伴可以参考下。 ...

    脚本之家3642020-04-25
  • GolangGolang中Bit数组的实现方式

    Golang中Bit数组的实现方式

    这篇文章主要介绍了Golang中Bit数组的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    天易独尊11682021-06-09
  • Golanggolang 通过ssh代理连接mysql的操作

    golang 通过ssh代理连接mysql的操作

    这篇文章主要介绍了golang 通过ssh代理连接mysql的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    a165861639710342021-03-08