-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
bugIt is confirmed a bug, but don't worry, we'll handle it.It is confirmed a bug, but don't worry, we'll handle it.doneThis issue is done, which may be release in next version.This issue is done, which may be release in next version.
Description
Go version
go version go1.23.1 darwin/arm64
GoFrame version
2.7.3
Can this bug be reproduced with the latest release?
Option Yes
What did you do?
如下是单测:
package test
import (
"fmt"
"testing"
"github.com/gogf/gf/v2/util/gconv"
)
type NullID string
type StructA struct {
Superior string `json:"superior"`
UpdatedTick int `json:"updated_tick"`
}
type StructB struct {
Superior *NullID `json:"superior"`
UpdatedTick *int `json:"updated_tick"`
}
type StructC struct {
Superior string `json:"superior"`
UpdatedTick int `json:"updated_tick"`
}
type StructD struct {
StructC
Superior *NullID `json:"superior"`
UpdatedTick *int `json:"updated_tick"`
}
type StructE struct {
Superior string `json:"superior"`
UpdatedTick int `json:"updated_tick"`
}
type StructF struct {
Superior *NullID `json:"superior"`
UpdatedTick *int `json:"updated_tick"`
StructE
}
type StructG struct {
Superior string `json:"superior"`
UpdatedTick int `json:"updated_tick"`
}
type StructH struct {
Superior *string `json:"superior"`
UpdatedTick *int `json:"updated_tick"`
StructG
}
type StructI struct {
Master struct {
Superior *NullID `json:"superior"`
UpdatedTick int `json:"updated_tick"`
} `json:"master"`
}
type StructJ struct {
StructA
Superior *NullID `json:"superior"`
UpdatedTick *int `json:"updated_tick"`
}
type StructK struct {
Master struct {
Superior *NullID `json:"superior"`
UpdatedTick int `json:"updated_tick"`
} `json:"master"`
}
type StructL struct {
Superior *NullID `json:"superior"`
UpdatedTick *int `json:"updated_tick"`
StructA
}
func TestScan(t *testing.T) {
// 测试1:没有结构嵌套,Superior为带字母的string,正常
fmt.Println("测试1")
structA := StructA{
Superior: "superior100",
UpdatedTick: 20,
}
structB := StructB{}
if err := gconv.Scan(structA, &structB); err != nil {
fmt.Printf("structA to structB: %s", err.Error())
}
fmt.Println("structB.Superior:", *structB.Superior)
fmt.Println("structB.UpdatedTick:", *structB.UpdatedTick)
// 测试2:没有结构嵌套,Superior为纯数字的string,正常
fmt.Println("测试2")
structA1 := StructA{
Superior: "100",
UpdatedTick: 20,
}
structB1 := StructB{}
if err := gconv.Scan(structA1, &structB1); err != nil {
fmt.Printf("structA1 to structB1: %s", err.Error())
}
fmt.Println("structB1.Superior:", *structB1.Superior)
fmt.Println("structB1.UpdatedTick:", *structB1.UpdatedTick)
// 测试3:结构嵌套,Superior为带字母的string,正常
fmt.Println("测试3")
structC := StructC{
Superior: "superior100",
UpdatedTick: 20,
}
structD := StructD{}
if err := gconv.Scan(structC, &structD); err != nil {
fmt.Printf("structC to structD: %s", err.Error())
}
fmt.Println("structD.StructC.Superior:", structD.StructC.Superior)
fmt.Println("structD.Superior:", *structD.Superior)
fmt.Println("structD.UpdatedTick:", *structD.UpdatedTick)
// 测试4:结构嵌套,Superior为纯数字的string,出现 structD1.Superior 值为 nil
fmt.Println("测试4")
structC1 := StructC{
Superior: "100",
UpdatedTick: 20,
}
structD1 := StructD{}
if err := gconv.Scan(structC1, &structD1); err != nil {
fmt.Printf("structC1 to structD1: %s", err.Error())
}
fmt.Println("structD1.StructC.Superior:", structD1.StructC.Superior) // structD1.StructC.Superior: 100
fmt.Println("structD1.Superior:", structD1.Superior) // structD1.Superior: <nil>
fmt.Println("structD1.UpdatedTick:", *structD1.UpdatedTick) // structD1.UpdatedTick: 20
// 测试5:结构嵌套,Superior为带字母的string,正常
fmt.Println("测试5")
structE := StructE{
Superior: "superior100",
UpdatedTick: 20,
}
structF := StructF{}
if err := gconv.Scan(structE, &structF); err != nil {
fmt.Printf("structE to structF: %s", err.Error())
}
fmt.Println("structF.StructE.Superior:", structF.StructE.Superior)
fmt.Println("structF.Superior:", *structF.Superior)
fmt.Println("structF.UpdatedTick:", *structF.UpdatedTick)
// 测试6:结构嵌套,Superior为纯数字的string,正常
fmt.Println("测试6")
structE1 := StructE{
Superior: "100",
UpdatedTick: 20,
}
structF1 := StructF{}
if err := gconv.Scan(structE1, &structF1); err != nil {
fmt.Printf("structE1 to structF1: %s\n", err.Error()) // 报错
}
fmt.Println("structF1.StructE.Superior:", structF1.StructE.Superior) // structF1.StructE.Superior: 100
fmt.Println("structF1.Superior:", *structF1.Superior) // structF1.Superior: 100
fmt.Println("structF1.UpdatedTick:", *structF1.UpdatedTick) // structF1.UpdatedTick: 20
// 测试7:结构嵌套,Superior为带字母的string,目标 Superior 类型 为 *string,正常
fmt.Println("测试7")
structG := StructG{
Superior: "superior100",
UpdatedTick: 20,
}
structH := StructH{}
if err := gconv.Scan(structG, &structH); err != nil {
fmt.Printf("structG to structH: %s\n", err.Error()) // 报错
}
fmt.Println("structH.StructG.Superior:", structH.StructG.Superior) // structH.StructG.Superior: superior100
fmt.Println("structH.Superior:", *structH.Superior) // structH.Superior: superior100
fmt.Println("structH.UpdatedTick:", *structH.UpdatedTick) // structH.UpdatedTick: 20
// 测试8:结构嵌套,Superior为纯数字的string,目标 Superior 类型 为 *string
// 报错 error binding srcValue to attribute "Superior": json.UnmarshalUseNumber failed: json: cannot unmarshal number into Go value of type string
fmt.Println("测试8")
structG1 := StructG{
Superior: "100",
UpdatedTick: 20,
}
structH1 := StructH{}
if err := gconv.Scan(structG1, &structH1); err != nil {
fmt.Printf("structG to structH: %s\n", err.Error()) // 报错
}
fmt.Println("structH1.StructG.Superior:", structH1.StructG.Superior) // structH1.StructG.Superior: ""
fmt.Println("structH1.Superior:", *structH1.Superior) // structH1.Superior: 100
fmt.Println("structH1.UpdatedTick:", structH1.UpdatedTick) // structH1.UpdatedTick: <nil>
// 测试9:结构嵌套,structJ.Superior 值为 nil
fmt.Println("测试9")
structI := StructI{}
xxx := NullID("superior100")
structI.Master.Superior = &xxx
structI.Master.UpdatedTick = 30
structJ := StructJ{}
if err := gconv.Scan(structI.Master, &structJ); err != nil {
fmt.Printf("structI to structJ: %s\n", err.Error()) // 报错
}
fmt.Println("structJ.StructA.Superior:", structJ.StructA.Superior) // structJ.StructA.Superior: superior100
fmt.Println("structJ.Superior:", structJ.Superior) // structJ.Superior: <nil>
fmt.Println("structJ.StructA.UpdatedTick:", structJ.StructA.UpdatedTick) // structJ.UpdatedTick: 30
fmt.Println("structJ.UpdatedTick:", *structJ.UpdatedTick) // structJ.UpdatedTick: 30
// 测试10:结构嵌套,正常
fmt.Println("测试10")
structK := StructK{}
yyy := NullID("superior100")
structK.Master.Superior = &yyy
structK.Master.UpdatedTick = 40
structL := StructL{}
if err := gconv.Scan(structK.Master, &structL); err != nil {
fmt.Printf("structK to structL: %s\n", err.Error()) // 报错
}
fmt.Println("structL.StructA.Superior:", structL.StructA.Superior) // structL.StructA.Superior: superior100
fmt.Println("structL.Superior:", *structL.Superior) // structL.Superior: superior100
fmt.Println("structL.StructA.UpdatedTick:", structL.StructA.UpdatedTick) // structJ.UpdatedTick: 30
fmt.Println("structL.UpdatedTick:", *structL.UpdatedTick) // structL.UpdatedTick: 30
}
What did you see happen?
参照上述单测结果
What did you expect to see?
向嵌套结构体中Scan数据时,内部不存在相同属性时,应该优先赋值外部同名属性,无论嵌套结构体的位置顺序如何
gqcngqcn
Metadata
Metadata
Assignees
Labels
bugIt is confirmed a bug, but don't worry, we'll handle it.It is confirmed a bug, but don't worry, we'll handle it.doneThis issue is done, which may be release in next version.This issue is done, which may be release in next version.