jeudi 3 février 2022

Set value of interface representing nil pointer using reflect in Go

My question is similar to How to initialize struct pointer via reflection.

I have an interface that represents a nil pointer. I want to update the value behind the nil pointer.

I took the code from one of the examples in the answers to the question mentioned above, but my situation is slightly different, and the given solution isn't working.

Inside InitNilPointer() the value actually does become &Foo{}. But the result at the call site remains (*Foo)(nil). How can I use reflect to update foo in main() to &Foo{}?

The situation is the following

func main() {
    var foo *Foo

    repository.InitNilPointer(foo)

    // Want: &main.Foo{A:""}
    fmt.Printf("Want: %+#v\n", &Foo{})

    // Got: (*main.Foo)(nil)
    fmt.Printf("Got: %+#v\n", foo)
}

// InitNilPointer initiates the given pointer to a nil value to become a pointer to 
// a value. E.g. (*Foo)(nil) becomes &Foo{}.
func InitNilPointer(source interface{}) {
    v := reflect.ValueOf(source)
    if reflect.Indirect(v).IsValid() {
        return
    }
    rv := reflect.ValueOf(&source).Elem()
    t := rv.Elem().Type().Elem()

    // This only updates the value locally. The call site still has a nil pointer. SAD.
    rv.Set(reflect.New(t))

    // source: &main.Foo{A:""}
    fmt.Printf("source: %+#v\n", source)
}




Aucun commentaire:

Enregistrer un commentaire