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

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语言range关键字循环时的坑

    Go语言range关键字循环时的坑

    今天小编就为大家分享一篇关于Go语言range关键字循环时的坑,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来...

    benben_20154202020-05-23
  • GolangGO语言字符串处理Strings包的函数使用示例讲解

    GO语言字符串处理Strings包的函数使用示例讲解

    这篇文章主要为大家介绍了GO语言字符串处理Strings包的函数使用示例讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加...

    Jeff的技术栈6882022-04-14
  • GolangGolang实现四种负载均衡的算法(随机,轮询等)

    Golang实现四种负载均衡的算法(随机,轮询等)

    本文介绍了示例介绍了Golang 负载均衡的四种实现,主要包括了随机,轮询,加权轮询负载,一致性hash,感兴趣的小伙伴们可以参考一下...

    Gundy_8442021-08-09
  • Golang深入浅析Go中三个点(...)用法

    深入浅析Go中三个点(...)用法

    这篇文章主要介绍了深入浅析Go中三个点(...)用法,需要的朋友可以参考下...

    踏雪无痕SS6472021-11-17
  • Golanggo语言获取系统盘符的方法

    go语言获取系统盘符的方法

    这篇文章主要介绍了go语言获取系统盘符的方法,涉及Go语言调用winapi获取系统硬件信息的技巧,具有一定参考借鉴价值,需要的朋友可以参考下 ...

    无尽海3862020-04-24
  • GolangGolang 语言极简类型转换库cast的使用详解

    Golang 语言极简类型转换库cast的使用详解

    本文我们通过 cast.ToString() 函数的使用,简单介绍了cast 的使用方法,除此之外,它还支持很多其他类型,在这没有多多介绍,对Golang 类型转换库 cast相关知...

    Golang语言开发栈6112021-12-02
  • GolangGo语言基础单元测试与性能测试示例详解

    Go语言基础单元测试与性能测试示例详解

    这篇文章主要为大家介绍了Go语言基础单元测试与性能测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助祝大家多多进步...

    枫少文7812021-12-05
  • GolangGo语言实现自动填写古诗词实例代码

    Go语言实现自动填写古诗词实例代码

    这篇文章主要给大家介绍了关于Go语言实现自动填写古诗词的相关资料,这是最近在项目中遇到的一个需求,文中通过示例代码介绍的非常详细,需要的朋...

    FengY5862020-05-14