mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
gconv改进
This commit is contained in:
@ -33,6 +33,8 @@ func Convert(i interface{}, t string, params...interface{}) interface{} {
|
||||
case "bool": return Bool(i)
|
||||
case "string": return String(i)
|
||||
case "[]byte": return Bytes(i)
|
||||
case "[]int": return Ints(i)
|
||||
case "[]string": return Strings(i)
|
||||
case "time.Time":
|
||||
if len(params) > 0 {
|
||||
return Time(i, String(params[0]))
|
||||
|
||||
157
g/util/gconv/gconv_slice.go
Normal file
157
g/util/gconv/gconv_slice.go
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
package gconv
|
||||
|
||||
import "fmt"
|
||||
|
||||
// 任意类型转换为[]int类型
|
||||
func Ints(i interface{}) []int {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
if r, ok := i.([]int); ok {
|
||||
return r
|
||||
} else {
|
||||
array := make([]int, 0)
|
||||
switch i.(type) {
|
||||
case []string:
|
||||
for _, v := range i.([]string) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []int8:
|
||||
for _, v := range i.([]int8) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []int16:
|
||||
for _, v := range i.([]int16) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []int32:
|
||||
for _, v := range i.([]int32) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []int64:
|
||||
for _, v := range i.([]int64) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []uint:
|
||||
for _, v := range i.([]uint) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []uint8:
|
||||
for _, v := range i.([]uint8) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []uint16:
|
||||
for _, v := range i.([]uint16) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []uint32:
|
||||
for _, v := range i.([]uint32) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []uint64:
|
||||
for _, v := range i.([]uint64) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []bool:
|
||||
for _, v := range i.([]bool) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []float32:
|
||||
for _, v := range i.([]float32) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []float64:
|
||||
for _, v := range i.([]float64) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
case []interface{}:
|
||||
for _, v := range i.([]interface{}) {
|
||||
array = append(array, Int(v))
|
||||
}
|
||||
}
|
||||
if len(array) > 0 {
|
||||
return array
|
||||
}
|
||||
}
|
||||
return []int{Int(i)}
|
||||
}
|
||||
|
||||
// 任意类型转换为[]string类型
|
||||
func Strings(i interface{}) []string {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
if r, ok := i.([]string); ok {
|
||||
return r
|
||||
} else {
|
||||
array := make([]string, 0)
|
||||
switch i.(type) {
|
||||
case []int:
|
||||
for _, v := range i.([]int) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []int8:
|
||||
for _, v := range i.([]int8) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []int16:
|
||||
for _, v := range i.([]int16) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []int32:
|
||||
for _, v := range i.([]int32) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []int64:
|
||||
for _, v := range i.([]int64) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint:
|
||||
for _, v := range i.([]uint) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint8:
|
||||
for _, v := range i.([]uint8) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint16:
|
||||
for _, v := range i.([]uint16) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint32:
|
||||
for _, v := range i.([]uint32) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint64:
|
||||
for _, v := range i.([]uint64) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []bool:
|
||||
for _, v := range i.([]bool) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []float32:
|
||||
for _, v := range i.([]float32) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []float64:
|
||||
for _, v := range i.([]float64) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []interface{}:
|
||||
for _, v := range i.([]interface{}) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
}
|
||||
if len(array) > 0 {
|
||||
return array
|
||||
}
|
||||
}
|
||||
return []string{fmt.Sprintf("%v", i)}
|
||||
}
|
||||
@ -1,83 +0,0 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
package gconv
|
||||
|
||||
import "fmt"
|
||||
|
||||
// 任意类型转换为[]string类型
|
||||
func Strings(i interface{}) []string {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
if r, ok := i.([]string); ok {
|
||||
return r
|
||||
} else {
|
||||
array := make([]string, 0)
|
||||
switch i.(type) {
|
||||
case []int:
|
||||
for _, v := range i.([]int) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []int8:
|
||||
for _, v := range i.([]int8) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []int16:
|
||||
for _, v := range i.([]int16) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []int32:
|
||||
for _, v := range i.([]int32) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []int64:
|
||||
for _, v := range i.([]int64) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint:
|
||||
for _, v := range i.([]uint) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint8:
|
||||
for _, v := range i.([]uint8) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint16:
|
||||
for _, v := range i.([]uint16) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint32:
|
||||
for _, v := range i.([]uint32) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []uint64:
|
||||
for _, v := range i.([]uint64) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []bool:
|
||||
for _, v := range i.([]bool) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []float32:
|
||||
for _, v := range i.([]float32) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []float64:
|
||||
for _, v := range i.([]float64) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
case []interface{}:
|
||||
for _, v := range i.([]interface{}) {
|
||||
array = append(array, String(v))
|
||||
}
|
||||
}
|
||||
if len(array) > 0 {
|
||||
return array
|
||||
}
|
||||
}
|
||||
return []string{fmt.Sprintf("%v", i)}
|
||||
}
|
||||
@ -11,6 +11,8 @@ import (
|
||||
"reflect"
|
||||
"github.com/fatih/structs"
|
||||
"strings"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 将params键值对参数映射到对应的struct对象属性上,第三个参数mapping为非必需,表示自定义名称与属性名称的映射关系。
|
||||
@ -40,7 +42,9 @@ func Struct(params interface{}, objPointer interface{}, attrMapping...map[string
|
||||
elem := reflect.ValueOf(objPointer).Elem()
|
||||
// 如果给定的参数不是map类型,那么直接将参数值映射到第一个属性上
|
||||
if !isParamMap {
|
||||
bindVarToStructByIndex(elem, 0, params)
|
||||
if err := bindVarToStructByIndex(elem, 0, params); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// 标签映射关系map,如果有的话
|
||||
@ -60,7 +64,9 @@ func Struct(params interface{}, objPointer interface{}, attrMapping...map[string
|
||||
for mappingk, mappingv := range attrMapping[0] {
|
||||
if v, ok := paramsMap[mappingk]; ok {
|
||||
dmap[mappingv] = true
|
||||
bindVarToStruct(elem, mappingv, v)
|
||||
if err := bindVarToStruct(elem, mappingv, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,7 +77,9 @@ func Struct(params interface{}, objPointer interface{}, attrMapping...map[string
|
||||
}
|
||||
if v, ok := paramsMap[tagk]; ok {
|
||||
dmap[tagv] = true
|
||||
bindVarToStruct(elem, tagv, v)
|
||||
if err := bindVarToStruct(elem, tagv, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
// 最后按照默认规则进行匹配
|
||||
@ -82,39 +90,43 @@ func Struct(params interface{}, objPointer interface{}, attrMapping...map[string
|
||||
}
|
||||
// 后续tag逻辑中会处理的key(重复的键名)这里便不处理
|
||||
if _, ok := tagmap[mapk]; !ok {
|
||||
bindVarToStruct(elem, name, mapv)
|
||||
if err := bindVarToStruct(elem, name, mapv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 将参数值绑定到对象指定名称的属性上
|
||||
func bindVarToStruct(elem reflect.Value, name string, value interface{}) {
|
||||
func bindVarToStruct(elem reflect.Value, name string, value interface{}) error {
|
||||
structFieldValue := elem.FieldByName(name)
|
||||
// 键名与对象属性匹配检测
|
||||
if !structFieldValue.IsValid() {
|
||||
return
|
||||
return errors.New(fmt.Sprintf(`invalid struct attribute of name "%s"`, name))
|
||||
}
|
||||
// CanSet的属性必须为公开属性(首字母大写)
|
||||
if !structFieldValue.CanSet() {
|
||||
return
|
||||
return errors.New(fmt.Sprintf(`struct attribute of name "%s" cannot be set`, name))
|
||||
}
|
||||
// 必须将value转换为struct属性的数据类型,这里必须用到gconv包
|
||||
structFieldValue.Set(reflect.ValueOf(Convert(value, structFieldValue.Type().String())))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 将参数值绑定到对象指定索引位置的属性上
|
||||
func bindVarToStructByIndex(elem reflect.Value, index int, value interface{}) {
|
||||
func bindVarToStructByIndex(elem reflect.Value, index int, value interface{}) error {
|
||||
structFieldValue := elem.FieldByIndex([]int{index})
|
||||
// 键名与对象属性匹配检测
|
||||
if !structFieldValue.IsValid() {
|
||||
return
|
||||
return errors.New(fmt.Sprintf("invalid struct attribute at index %d", index))
|
||||
}
|
||||
// CanSet的属性必须为公开属性(首字母大写)
|
||||
if !structFieldValue.CanSet() {
|
||||
return
|
||||
return errors.New(fmt.Sprintf("struct attribute cannot be set at index %d", index))
|
||||
}
|
||||
// 必须将value转换为struct属性的数据类型,这里必须用到gconv包
|
||||
structFieldValue.Set(reflect.ValueOf(Convert(value, structFieldValue.Type().String())))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -1,19 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/os/glog"
|
||||
"time"
|
||||
"gitee.com/johng/gf/g"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
g.Config().AddPath("eeee")
|
||||
g.Config().AddPath(".")
|
||||
glog.SetPath(g.Config().GetString("logPath"))
|
||||
glog.SetPath("/tmp/test-logs")
|
||||
for {
|
||||
glog.Println("1")
|
||||
time.Sleep(time.Second)
|
||||
type B struct {
|
||||
Name string
|
||||
}
|
||||
type A struct {
|
||||
Name string
|
||||
Child B
|
||||
}
|
||||
|
||||
a := A {
|
||||
Name : "A",
|
||||
Child : B {
|
||||
Name : "B",
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(a)
|
||||
a2 := new(A)
|
||||
json.Unmarshal(b, a2)
|
||||
fmt.Println(*a2)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user