Omri. B
Omri. B

Reputation: 462

Convert golang []interface{} into a list of structs

I am trying to do the following: Given a target struct targetModel, which is a basic struct e.g User, convert a list of these structs that are saved as bytes into a golang list of structs. Here is my latest attempt, which does not compile:

func (r *RedisWrapper) GetList(ctx context.Context, key string, targetModel interface{}) (interface{}, error) {
    object, err := r.redis.Get(ctx, key).Result()

    if err == nil {
        copiedSlice := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(targetModel).Elem()), 0, 0).Interface()
        copiedModel := make([]interface{}, 0)
        err = json.Unmarshal([]byte(object), &copiedModel) //copiedModel := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(targetModel)), 0, 0).Interface()
        //err = json.Unmarshal([]byte(object), &copiedModel)
        if err != nil {
            logrus.Errorf("Failed to unmarshal object %s with key %s into %#v with err %s", object, key, targetModel, err)
            return nil, err
        }
        for _, i := range copiedModel {
            copiedSlice = append(copiedSlice, i)

        }
        return copiedModel, nil
    }

    return nil, err

}

I am:

The append function fails as Cannot use 'copiedSlice' (type any) as the type []Type I'm not sure why this happens. Ideally, and what I initially tried, was to simply unmarshal like that, but that failed miserably. I would rather avoid iterating if I can, but I don't mind it so much. Thank you

Upvotes: 0

Views: 235

Answers (1)

mkopriva
mkopriva

Reputation: 38313

func GetList(targetModel interface{}) (interface{}, error) {
    object, err := redis_data()
    if err != nil {
        return nil, err
    }

    dst := reflect.New(reflect.SliceOf(reflect.TypeOf(targetModel).Elem()))
    if err := json.Unmarshal([]byte(object), dst.Interface()); err != nil {
        return nil, err
    }

    return dst.Elem().Interface(), nil

}

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

Upvotes: 1

Related Questions