feat: 深度克隆支持map复制
This commit is contained in:
1
go.mod
1
go.mod
@ -27,6 +27,7 @@ require (
|
|||||||
github.com/smarty/assertions v1.15.0 // indirect
|
github.com/smarty/assertions v1.15.0 // indirect
|
||||||
github.com/tidwall/match v1.2.0 // indirect
|
github.com/tidwall/match v1.2.0 // indirect
|
||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
|
github.com/tidwall/sjson v1.2.5 // indirect
|
||||||
golang.org/x/mod v0.9.0 // indirect
|
golang.org/x/mod v0.9.0 // indirect
|
||||||
golang.org/x/sys v0.6.0 // indirect
|
golang.org/x/sys v0.6.0 // indirect
|
||||||
golang.org/x/tools v0.7.0 // indirect
|
golang.org/x/tools v0.7.0 // indirect
|
||||||
|
|||||||
3
go.sum
3
go.sum
@ -44,6 +44,7 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
|
|||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
|
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
@ -52,6 +53,8 @@ github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
|
|||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||||
|
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||||
|
|||||||
@ -9,6 +9,7 @@ package op_array
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ToMap 数组转map
|
// ToMap 数组转map
|
||||||
@ -112,3 +113,34 @@ func Tree[ID comparable, Value any](dataList []Value, formatParentID func(v Valu
|
|||||||
}
|
}
|
||||||
return rootData
|
return rootData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepClone 深度克隆一个数组, 每一个元素的地址均重新分配
|
||||||
|
func DeepClone[Value any](dataList []Value) []Value {
|
||||||
|
v := *new(Value)
|
||||||
|
vType := reflect.TypeOf(v)
|
||||||
|
res := make([]Value, len(dataList))
|
||||||
|
for i := 0; i < len(dataList); i++ {
|
||||||
|
newV := new(Value)
|
||||||
|
switch vType.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
// 解引用, 并单独读取值后重新分配地址
|
||||||
|
copyV := reflect.New(vType.Elem()).Elem()
|
||||||
|
copyV.Set(reflect.ValueOf(dataList[i]).Elem())
|
||||||
|
*newV = copyV.Addr().Interface().(Value)
|
||||||
|
case reflect.Map:
|
||||||
|
mapVal := reflect.ValueOf(dataList[i])
|
||||||
|
mapKeyList := mapVal.MapKeys()
|
||||||
|
newMap := reflect.MakeMap(vType)
|
||||||
|
for _, key := range mapKeyList {
|
||||||
|
// 通过键获取对应的值
|
||||||
|
value := mapVal.MapIndex(key)
|
||||||
|
newMap.SetMapIndex(key, value)
|
||||||
|
}
|
||||||
|
*newV = newMap.Interface().(Value)
|
||||||
|
default:
|
||||||
|
*newV = dataList[i]
|
||||||
|
}
|
||||||
|
res[i] = *newV
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
package op_array
|
package op_array
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||||
@ -32,3 +33,38 @@ func TestTree(t *testing.T) {
|
|||||||
res := Tree(dataList, func(v Data) int { return v.ParentID }, func(v Data) int { return v.ID })
|
res := Tree(dataList, func(v Data) int { return v.ParentID }, func(v Data) int { return v.ID })
|
||||||
serialize.JSON.ConsoleOutput(res)
|
serialize.JSON.ConsoleOutput(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClone(t *testing.T) {
|
||||||
|
type Data struct {
|
||||||
|
ID int `json:"id" dc:"数据ID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字面结构体
|
||||||
|
dataList := []Data{
|
||||||
|
{ID: 1},
|
||||||
|
{ID: 2},
|
||||||
|
}
|
||||||
|
res := DeepClone(dataList)
|
||||||
|
fmt.Println(fmt.Sprintf("%p", &res[0]), fmt.Sprintf("%p", &dataList[0]))
|
||||||
|
fmt.Println(fmt.Sprintf("%p", &res[1]), fmt.Sprintf("%p", &dataList[1]))
|
||||||
|
|
||||||
|
// 结构体指针
|
||||||
|
dataList1 := []*Data{
|
||||||
|
{ID: 1},
|
||||||
|
{ID: 2},
|
||||||
|
}
|
||||||
|
res1 := DeepClone(dataList1)
|
||||||
|
fmt.Println(fmt.Sprintf("%p", &res1[0]), fmt.Sprintf("%p", &dataList1[0]))
|
||||||
|
fmt.Println(fmt.Sprintf("%p", &res1[1]), fmt.Sprintf("%p", &dataList1[1]))
|
||||||
|
|
||||||
|
// Map数据
|
||||||
|
dataList2 := []map[string]any{
|
||||||
|
{"id": 1},
|
||||||
|
{"id": 2},
|
||||||
|
}
|
||||||
|
res2 := DeepClone(dataList2)
|
||||||
|
fmt.Println(fmt.Sprintf("%p", &res2[0]), fmt.Sprintf("%p", &dataList2[0]))
|
||||||
|
fmt.Println(fmt.Sprintf("%p", &res2[1]), fmt.Sprintf("%p", &dataList2[1]))
|
||||||
|
serialize.JSON.ConsoleOutput(res2)
|
||||||
|
serialize.JSON.ConsoleOutput(dataList2)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user