From 465e692db2c87e12be9de32a57a9aa3d0285d5fc Mon Sep 17 00:00:00 2001 From: Yusuf Efe <120668197+yuefdev@users.noreply.github.com> Date: Mon, 19 Oct 2026 01:57:54 +0300 Subject: [PATCH] fix: preserve initial values in pointer-to-struct slices --- env.go | 11 ++++++----- slice_pointer_defaults_test.go | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 slice_pointer_defaults_test.go diff --git a/env.go b/env.go index c3ac260a..83802958 100644 --- a/env.go +++ b/env.go @@ -461,13 +461,14 @@ func doParseSlice(ref reflect.Value, processField processFieldFn, opts Options) } sliceType := ref.Type() + initial := ref var initialized int if reflect.Pointer == ref.Kind() { sliceType = sliceType.Elem() - // Due to the rest of code the pre-initialized slice has no chance for this situation - initialized = 0 - } else { - initialized = ref.Len() + initial = ref.Elem() + } + if initial.IsValid() { + initialized = initial.Len() } var capacity int @@ -478,7 +479,7 @@ func doParseSlice(ref reflect.Value, processField processFieldFn, opts Options) for i := 0; i < capacity; i++ { item := result.Index(i) if i < initialized { - item.Set(ref.Index(i)) + item.Set(initial.Index(i)) } if err := doParse(item, processField, optionsWithSliceEnvPrefix(opts, i)); err != nil { return err diff --git a/slice_pointer_defaults_test.go b/slice_pointer_defaults_test.go new file mode 100644 index 00000000..9fba66f9 --- /dev/null +++ b/slice_pointer_defaults_test.go @@ -0,0 +1,17 @@ +package env + +import "testing" + +func TestSlicePointerPreservesInitialValues(t *testing.T) { + type item struct { + Name string `env:"NAME"` + Port int `env:"PORT"` + } + items := []item{{Name: "first", Port: 8080}, {Name: "second", Port: 9090}} + cfg := struct { + Items *[]item `envPrefix:"ITEMS_"` + }{Items: &items} + err := ParseWithOptions(&cfg, Options{Environment: map[string]string{"ITEMS_0_NAME": "updated"}}) + isNoErr(t, err) + isEqual(t, []item{{Name: "updated", Port: 8080}, {Name: "second", Port: 9090}}, *cfg.Items) +}