Skip to content

Commit 1ff8c1d

Browse files
committed
Value() 添加对数组的支持
1 parent 152d1cc commit 1ff8c1d

File tree

3 files changed

+88
-11
lines changed

3 files changed

+88
-11
lines changed

obj.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
)
1212

1313
// FieldConvert 字段转换
14-
// 用于 map 转换到一个对象实例或是从一个对象实例转换到 map
14+
// 用于 map 转换到一个对象实例或是从一个对象实例转换到 map 时,字段名称的转换。
1515
type FieldConvert func(src string) (dest string)
1616

1717
// FieldConvert 的默认实现
@@ -84,7 +84,7 @@ func Map2Obj(src interface{}, dest interface{}, conv FieldConvert) error {
8484
k := keys[i]
8585

8686
if k.Kind() != reflect.String {
87-
return errors.New("src必须为map[string]interface{}类型")
87+
return errors.New("src 必须为 map[string]interface{} 类型")
8888
}
8989

9090
srcItemVal := srcVal.MapIndex(k)
@@ -135,13 +135,13 @@ func Map2Obj(src interface{}, dest interface{}, conv FieldConvert) error {
135135
func map2ObjCheck(src interface{}, dest interface{}, conv FieldConvert) (srcVal reflect.Value, destVal reflect.Value, fun FieldConvert, err error) {
136136
destVal = reflect.ValueOf(dest)
137137
if destVal.Kind() != reflect.Ptr {
138-
err = fmt.Errorf("dest必须为一个struct对象的指针,实际类型为[%v]", destVal.Type())
138+
err = fmt.Errorf("dest 必须为一个 struct 对象的指针,实际类型为[%v]", destVal.Type())
139139
return
140140
}
141141

142142
destVal = destVal.Elem()
143143
if destVal.Kind() != reflect.Struct {
144-
err = fmt.Errorf("dest必须为一个struct对象的指针,实际类型为[%v]", destVal.Type())
144+
err = fmt.Errorf("dest 必须为一个 struct 对象的指针,实际类型为[%v]", destVal.Type())
145145
return
146146
}
147147

@@ -152,7 +152,7 @@ func map2ObjCheck(src interface{}, dest interface{}, conv FieldConvert) (srcVal
152152
}
153153

154154
if srcVal.Kind() != reflect.Map {
155-
err = fmt.Errorf("src必须为map类型或是map指针,实际类型为[%v]", srcVal.Type())
155+
err = fmt.Errorf("src 必须为 map 类型或是 map 指针,实际类型为[%v]", srcVal.Type())
156156
return
157157
}
158158

value.go

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,68 @@ func Value(source interface{}, target reflect.Value) error {
6767
return err
6868
}
6969
target.SetString(val)
70-
default:
71-
sourceValue := reflect.ValueOf(source)
72-
targetType := target.Type()
73-
if !sourceValue.Type().ConvertibleTo(targetType) {
74-
return typeError(source, targetType.String())
70+
case reflect.Slice:
71+
s := reflect.ValueOf(source)
72+
sk := s.Kind()
73+
tek := target.Type().Elem().Kind()
74+
75+
// []byte []rune 和 string 之间可以互相转换
76+
if sk == reflect.String && (tek == reflect.Uint8 || tek == reflect.Int32) {
77+
return valueDefault(source, target)
78+
}
79+
80+
if sk != reflect.Array && sk != reflect.Slice {
81+
return typeError(source, "slice")
82+
}
83+
84+
l := s.Len()
85+
tmp := reflect.MakeSlice(target.Type(), l, l)
86+
for i := 0; i < l; i++ {
87+
si := s.Index(i).Interface()
88+
if err := Value(si, tmp.Index(i)); err != nil {
89+
return err
90+
}
91+
}
92+
target.Set(tmp)
93+
case reflect.Array:
94+
s := reflect.ValueOf(source)
95+
sk := s.Kind()
96+
tek := target.Type().Elem().Kind()
97+
98+
// []byte []rune 和 string 之间可以互相转换
99+
if sk == reflect.String && (tek == reflect.Uint8 || tek == reflect.Int32) {
100+
return valueDefault(source, target)
101+
}
102+
103+
if sk != reflect.Array && sk != reflect.Slice {
104+
return typeError(source, "array")
75105
}
76-
target.Set(sourceValue.Convert(targetType))
106+
107+
l := s.Len()
108+
if l != target.Len() {
109+
return fmt.Errorf("两者长度不一样,无法转换 %d: %d", l, target.Len())
110+
}
111+
112+
for i := 0; i < l; i++ {
113+
si := s.Index(i).Interface()
114+
if err := Value(si, target.Index(i)); err != nil {
115+
return err
116+
}
117+
}
118+
default:
119+
return valueDefault(source, target)
120+
}
121+
122+
return nil
123+
}
124+
125+
func valueDefault(source interface{}, target reflect.Value) error {
126+
sourceValue := reflect.ValueOf(source)
127+
targetType := target.Type()
128+
if !sourceValue.Type().ConvertibleTo(targetType) {
129+
return typeError(source, targetType.String())
77130
}
131+
target.Set(sourceValue.Convert(targetType))
78132

79133
return nil
80134
}

value_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,29 @@ func TestValue(t *testing.T) {
7373
a.NotError(Value(nil, reflect.ValueOf(&t12)))
7474
a.Equal("", t12)
7575

76+
s13 := []string{"4", "5", "6"}
77+
t13 := []int{1, 2}
78+
a.NotError(Value(s13, reflect.ValueOf(&t13)))
79+
a.Equal([]int{4, 5, 6}, t13)
80+
81+
// array 转换
82+
s14 := []string{"4", "5"}
83+
t14 := [2]int{1, 2}
84+
a.NotError(Value(s14, reflect.ValueOf(&t14)))
85+
a.Equal([]int{4, 5}, t14)
86+
87+
// array 长度不一样,无法转换
88+
s15 := []string{"4", "5", "6"}
89+
t15 := [2]int{1, 2}
90+
a.Error(Value(s15, reflect.ValueOf(&t15)))
91+
a.Equal([]int{1, 2}, t15)
92+
93+
// slice 长度不同,可以转换
94+
s16 := []string{"4", "5"}
95+
t16 := []int{1, 2, 3}
96+
a.NotError(Value(s16, reflect.ValueOf(&t16)))
97+
a.Equal([]int{4, 5}, t16)
98+
7699
// 无法转换的
77100
s20 := "1a23"
78101
t20 := 444

0 commit comments

Comments
 (0)