1

I have the following code that mocks the structure of a code I'm working on. The main idea is that the ListOf function receives an array of some struct and populates it with elements created using reflection. The type of the structs is unknown so it must work with "any" type, this is why the list parameter is passed as interface{}. This part seems to be working: elements are created and appended to the array.

Before appending to the the array, the elements must be passed to the SetValue function which expects a pointer to a struct in order to modify the struct it receives.

In the code below I'm mocking this function, its internal logic is not relevant because I don't control this function. I cannot change it and, as far as I have tested, if this function receives a pointer to a struct it works as expected.

However, I have been unable to find a way to pass a pointer to the new created struct to the SetValue function. When I run the code below I get the following error:

panic: interface conversion: interface {} is main.MyStruct, not *main.MyStruct

The question I have is, how can I modify ListOf to be able to pass a *main.MyStruct to the SetValue function. Apparently I'm missing something simple here.

This is the code. You can try it at the Go Playground. Thanks in advance.

package main

import (
         "fmt"
         "reflect"
)

type MyStruct struct {
     Metadata struct {
        Name string
    }
}

// Expects a pointer to an struct and modifies it
func SetValue(obj interface{}) {
    // This code mocks the logic that modifies the generic objects
    // It only shows that I need a pointer in order to modify obj
    // I don't control this logic.
    s := obj.(*MyStruct)
    s.Metadata.Name = "name"
}

func ListOf(list interface{}) {
    // type of the elements of the list (main.MyStruct)
    e := reflect.TypeOf(list).Elem().Elem()
    // new value of type main.MyStruct
    v := reflect.New(e)
    // Call SetName, here is where I need *main.MyStruct
    SetValue(v.Elem().Interface())
    // value of list used below
    l := reflect.ValueOf(list).Elem()
    // append new value to list
    l.Set(reflect.Append(l, v.Elem()))
}

func main() {
    list := []MyStruct{}
    ListOf(&list)
    fmt.Printf("%v", list)
}

1 Answer 1

3

New returns a value with a *main.MyStruct. Pass that value to SetValue:

v := reflect.New(e)
SetValue(v.Interface())

https://go.dev/play/p/vJwbfGj7YZF

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.