user568109
user568109

Reputation: 48003

How to modify object and struct from an existing struct?

I have a struct say

type person struct{
    name string
    phone string
    address string
}

and I want to transform it to this (modify phone and address) I only have the object not the struct.

type person2 struct {
    name  string
    phone []struct {
        value string
    }

    address []struct {
        value string
    }
}

How can I create new struct based on one I have ? I want to transform selected fields only.

I looked into reflection but don't know where to start/how to use it.

Upvotes: 1

Views: 85

Answers (1)

icza
icza

Reputation: 417652

Foreword: if you only have the type person and not person2, you have to first write person2. Go is statically typed language, you can't just create person2 at runtime. You may write person2 manually or use go generate by writing the generator code yourself, but it won't be any simpler.

You could also use something like map[string]interface{} to mimic a dynamic struct, but that won't be any friendlier nor faster. Not to mention you'd have to use type assertions as value type is interface{}...


To create a value of person2 from a value of person, you don't need reflection, you can simply manually code it:

func transform(p person) person2 {
    return person2{
        p.name,
        []struct{ value string }{{p.phone}},
        []struct{ value string }{{p.address}},
    }
}

Note that this may look a little weird, and that's because you used a slice of anonymous struct for person2.phone and person2.address, and to initialize an anonymous struct with a composite literal, the anonymous struct definition has to be repeated.

Testing it:

p := person{"Bob", "1234", "New York"}
fmt.Println(p)
p2 := transform(p)
fmt.Println(p2)

Output (try it on the Go Playground):

{Bob 1234 New York}
{Bob [{1234}] [{New York}]}

Note:

Note that your person2 is unnecessarily complex. It could be as simple as this:

type person2 struct {
    name      string
    phones    []string
    addresses []string
}

And then the transformation is a one-liner:

func transform(p person) person2 {
    return person2{p.name, []string{p.phone}, []string{p.address}}
}

Output (try it on the Go Playground):

{Bob 1234 New York}
{Bob [1234] [New York]}

Upvotes: 4

Related Questions