diff --git a/util/gconv/gconv_z_unit_issue_test.go b/util/gconv/gconv_z_unit_issue_test.go index 234f1e9036a..76443df9e6a 100644 --- a/util/gconv/gconv_z_unit_issue_test.go +++ b/util/gconv/gconv_z_unit_issue_test.go @@ -806,6 +806,41 @@ func Test_Issue3903(t *testing.T) { }) } +// https://github.com/gogf/gf/issues/4218 +func Test_Issue4218(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + type SysMenuVo struct { + MenuId int64 `json:"menuId" orm:"menu_id"` + MenuName string `json:"menuName" orm:"menu_name"` + Children []*SysMenuVo `json:"children" orm:"children"` + ParentId int64 `json:"parentId" orm:"parent_id"` + } + menus := []*SysMenuVo{ + { + MenuId: 1, + MenuName: "系统管理", + ParentId: 0, + }, + { + MenuId: 2, + MenuName: "字典查询", + ParentId: 1, + }, + } + var parent *SysMenuVo + err := gconv.Scan(menus[0], &parent) + t.AssertNil(err) + t.Assert(parent.MenuId, 1) + t.Assert(parent.ParentId, 0) + + parent.Children = append(parent.Children, menus[1]) + + t.Assert(len(menus[0].Children), 1) + t.Assert(menus[0].Children[0].MenuId, 2) + t.Assert(menus[0].Children[0].ParentId, 1) + }) +} + // https://github.com/gogf/gf/issues/4542 func Test_Issue4542(t *testing.T) { // Test case 1: Nested map conversion - map[string]any to map[string]map[string]float64 diff --git a/util/gconv/internal/converter/converter_scan.go b/util/gconv/internal/converter/converter_scan.go index ad06d3848f1..feb7cadcbe8 100644 --- a/util/gconv/internal/converter/converter_scan.go +++ b/util/gconv/internal/converter/converter_scan.go @@ -96,11 +96,14 @@ func (c *Converter) Scan(srcValue any, dstPointer any, option ...ScanOption) (er } // Get the element type and kind of dstPointer - var ( - dstPointerReflectValueElem = dstPointerReflectValue.Elem() - dstPointerReflectValueElemKind = dstPointerReflectValueElem.Kind() - ) + var dstPointerReflectValueElem = dstPointerReflectValue.Elem() + // Check if srcValue and dstPointer are the same type, in which case direct assignment can be performed + if ok := c.doConvertWithTypeCheck(srcValueReflectValue, dstPointerReflectValueElem); ok { + return nil + } + // Handle multiple level pointers + var dstPointerReflectValueElemKind = dstPointerReflectValueElem.Kind() if dstPointerReflectValueElemKind == reflect.Pointer { if dstPointerReflectValueElem.IsNil() { // Create a new value for the pointer dereference @@ -114,11 +117,6 @@ func (c *Converter) Scan(srcValue any, dstPointer any, option ...ScanOption) (er return c.Scan(srcValueReflectValue, dstPointerReflectValueElem, option...) } - // Check if srcValue and dstPointer are the same type, in which case direct assignment can be performed - if ok := c.doConvertWithTypeCheck(srcValueReflectValue, dstPointerReflectValueElem); ok { - return nil - } - scanOption := c.getScanOption(option...) // Handle different destination types switch dstPointerReflectValueElemKind {