diff --git a/conf/bind.go b/conf/bind.go index 9a692d53..a3d15f42 100644 --- a/conf/bind.go +++ b/conf/bind.go @@ -227,11 +227,16 @@ func bindSlice(p *Properties, v reflect.Value, t reflect.Type, param BindParam, } for i := 0; ; i++ { - e := reflect.New(et).Elem() subParam := BindParam{ Key: fmt.Sprintf("%s[%d]", param.Key, i), Path: fmt.Sprintf("%s[%d]", param.Path, i), } + + if !p.Has(subParam.Key) { + break + } + + e := reflect.New(et).Elem() err = BindValue(p, e, et, subParam, filter) if errors.Is(err, errNotExist) { break diff --git a/conf/bind_test.go b/conf/bind_test.go index 895ec253..52d41040 100644 --- a/conf/bind_test.go +++ b/conf/bind_test.go @@ -779,6 +779,41 @@ func TestBind_SliceValue(t *testing.T) { }, }) }) + + t.Run("structs#2", func(t *testing.T) { + type AppSecret struct { + AppId string `value:"${appid:=}"` + AppUrl string `value:"${appurl:=}"` + AppKey string `value:"${appkey:=}"` + } + + type BaseChannel struct { + Extends []AppSecret `value:"${extends:=}"` + } + + type UserPwd struct { + BaseChannel `value:"${sdk.userpwd}"` + } + + var channel UserPwd + err := assert.Must(Map(map[string]interface{}{ + "sdk.userpwd.extends[0].appid": "app1", + "sdk.userpwd.extends[0].appurl": "//app1", + "sdk.userpwd.extends[0].appkey": "app1key", + "sdk.userpwd.extends[1].appid": "app2", + "sdk.userpwd.extends[1].appurl": "//app2", + "sdk.userpwd.extends[1].appkey": "app2key", + })).Bind(&channel, Tag("${}")) + assert.Nil(t, err) + assert.Equal(t, channel, UserPwd{ + BaseChannel{ + Extends: []AppSecret{ + {AppId: "app1", AppUrl: "//app1", AppKey: "app1key"}, + {AppId: "app2", AppUrl: "//app2", AppKey: "app2key"}, + }, + }, + }) + }) } func TestBind_MapValue(t *testing.T) {