go-utils
介绍
golang工具库,强化golang基础功能,提高开发效率;
安装教程
go get gitee.com/fmldd/go-utils
使用说明
typeplus基础类型增强包
sqltype实现了对golang中database/sql包内NullInt32,NullInt64,NullFloat64,NullString,NullBool,NullTime类型对象的增强,实现了Marshaler,Unmarshaler接口,json的序列化和反序列化变直接针对其内部包装的基础数据类型,不会引入附件数据;
json序列化示例:
package main
import (
"database/sql"
"encoding/json"
"fmt"
"gitee.com/fmldd/go-utils/typeplus/sqltype"
"time"
)
//model
type Person struct {
Name sqltype.NullString
Age sqltype.NullInt32
Birthday sqltype.NullTime
}
func main() {
tm, _ := time.Parse("2006-01-02 15:04:05", "2006-01-02 15:04:05")
person := Person{
Name: sqltype.NullString{sql.NullString{
String: "PatrickStar",
Valid: true,
}},
Age: sqltype.NullInt32{sql.NullInt32{
Int32: 0,
Valid: false,
}},
Birthday: sqltype.NullTime{sql.NullTime{
Time: tm,
Valid: true,
}},
}
data, _ := json.Marshal(person)
str := "{\"Name\":\"PatrickStar\",\"Age\":null,\"Birthday\":\"2006-01-02T15:04:05Z\"}"
fmt.Println(string(data) == str)
}
json反序列化示例:
package main
import (
"database/sql"
"encoding/json"
"fmt"
"gitee.com/fmldd/go-utils/typeplus/sqltype"
"reflect"
"time"
)
//model
type Person struct {
Name sqltype.NullString
Age sqltype.NullInt32
Birthday sqltype.NullTime
}
func main() {
tm, _ := time.Parse("2006-01-02 15:04:05", "2006-01-02 15:04:05")
p1 := Person{
Name: sqltype.NullString{sql.NullString{
String: "PatrickStar",
Valid: true,
}},
Age: sqltype.NullInt32{sql.NullInt32{
Int32: 0,
Valid: false,
}},
Birthday: sqltype.NullTime{sql.NullTime{
Time: tm,
Valid: true,
}},
}
p2 := Person{}
json.Unmarshal([]byte("{\"Name\":\"PatrickStar\",\"Age\":null,\"Birthday\":\"2006-01-02T15:04:05Z\"}"), &p2)
fmt.Println(reflect.DeepEqual(p1, p2))
}
copy对象复制包
1.提供基于json的数据复制的一般实现,但性能较低(1次序列化与1次反序列,性能损耗较高),源码如下:
func JsonCopy(source interface{}, target interface{}) (err error) {
sByte, err := json.Marshal(source)
if err != nil {
return err
}
return json.Unmarshal(sByte, target)
}
示例1:
package main
import (
"fmt"
"gitee.com/fmldd/go-utils/copy"
"reflect"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age,string"`
}
type User struct {
Name string `json:"name"`
Age string `json:"age"`
}
func main() {
p := Person{
Name: "Patrick Star",
Age: 2,
}
u1 := User{}
u2 := User{
Name: "Patrick Star",
Age: "2",
}
copy.JsonCopy(p, &u1)
fmt.Println(reflect.DeepEqual(u1, u2))
}
2.提供基于反射的数据复制的实现,参考 copier, 与copier不同的是,为了避免引入新的结构体标签,这里使用json的标签作为复制的标识符号,支持如下格式的标签
格式 |
描述 |
`json:"-"` |
复制时忽略该字段 |
`json:"label_name,must"` |
字段未能复制时抛出错误 |
`json:"label_name,omitempty"` |
字段为空时不复制 |
示例2-1:
package main
import (
"fmt"
"gitee.com/fmldd/go-utils/copy"
"reflect"
)
type User struct {
Age int `json:"Age"`
Name string `json:"Name"`
}
type Person struct {
Age int `json:"Age"`
Name string `json:"Name"`
}
func main() {
p := Person{
Name: "Patrick Star",
Age: 2,
}
u1 := User{}
u2 := User{
Name: "Patrick Star",
Age: 2,
}
copy.Copy(p, &u1)
fmt.Println(reflect.DeepEqual(u1, u2))
}
2.提供基于反射的
示例2-2
package main
import (
"fmt"
"gitee.com/fmldd/go-utils/copy"
"time"
)
type PerSonDetail struct {
Age int `json:"age"`
Birthday time.Time
Friends []Person
}
type Person struct {
Name string `json:"name"`
Sex string `json:"sex"`
Detail PerSonDetail `json:"detail"`
}
type StudentDetail struct {
Age int `json:"age"`
Birthday time.Time `json:"birthday"`
Friends []Student
}
type Student struct {
ID string `json:"-"`
Name string `json:"name"`
Sex string `json:"sex"`
StdDetail StudentDetail `json:"detail"`
}
func main() {
tm, _ := time.Parse("2006-01-02 15:04:05", "2006-01-02 15:04:05")
ps := Person{
Name: "Patrick Star",
Sex: "boy",
Detail: PerSonDetail{
Age: 2,
Birthday: tm,
Friends: nil,
},
}
sb := Person{
Name: "Sponge Bob",
Sex: "boy",
Detail: PerSonDetail{
Age: 2,
Birthday: tm,
Friends: nil,
},
}
fs := make([]Person, 2)
fs[0] = ps
fs[1] = sb
sc := Person{
Name: "Sandy Cheeks",
Sex: "girl",
Detail: PerSonDetail{
Age: 2,
Birthday: tm,
Friends: fs,
},
}
st := Student{}
copy.Copy(sc, &st)
fmt.Println(st)
}
3.提供扩展,你可以实现go-utils的CanSet或golang的Scaner接口来自定义copy的过程
示例3:
package main
import (
"fmt"
"gitee.com/fmldd/go-utils/copy"
"reflect"
"strconv"
)
type Src struct {
Age string `json:"age"`
}
type Des struct {
Age CanSerDes `json:"age"`
}
type CanSerDes struct {
Age int `json:"age"`
}
func (c *CanSerDes) Set(v interface{}) (err error) {
vType, _ := copy.KindType(reflect.TypeOf(v))
vValue := copy.KindValue(reflect.ValueOf(v))
cType := reflect.TypeOf(c.Age)
cValue := reflect.ValueOf(&c.Age)
if vType.ConvertibleTo(cType) {
cValue.Set(vValue.Convert(cType))
} else if vType.Kind() == reflect.String {
str := vValue.String()
c.Age, err = strconv.Atoi(str)
return err
} else {
return copy.ErrNotSupported
}
return nil
}
func main() {
src := Src{Age: "12"}
des := Des{}
copy.Copy(src, &des)
fmt.Println(des)
}
发布计划
1.参数自动校验
2.自动配置
参与贡献
- Fork 本仓库
- 新建 Feat_xxx 分支
- 提交代码
- 新建 Pull Request