Helper func to assign respective data to its key

Viewed 38

So I have this data struct:

type Parent struct {
    A ChildA
    B ChildB
    C ChildC
    D ChildD
}

type ChildA struct {
    ...

}

I am trying to create a helper funct such that I can reduce my LOC when it comes to variable assignment.

What I am trying to do:

func SomeHelper( SomeChild Child? ) Parent {
    return Parent{
        ?: SomeChild
    }
}

"?" can be any of the key A B C D

2 Answers

We can use variadic function and reflection.

this is the example code:

package main

import (
    "errors"
    "fmt"
    "reflect"
)

type Parent struct {
    A ChildA
    B ChildB
    C ChildC
    D ChildD
}

type ChildA struct {
    x string
}

type ChildB struct {
    x string
}

type ChildC struct {
}

type ChildD struct {
}

func helper(childs ...any) (Parent, error) {
    check := make(map[string]int)
    var p Parent

    for _, v := range childs {
        if v == nil {
            continue
        }
        childType := reflect.TypeOf(v)

        check[childType.String()]++

        if check[childType.String()] > 1 {
            return p, errors.New("child must be unique")
        }

        switch childType.String() {
        case "main.ChildA":
            p.A = v.(ChildA)
        case "main.ChildB":
            p.B = v.(ChildB)
        case "main.ChildC":
            p.C = v.(ChildC)
        case "main.ChildD":
            p.D = v.(ChildD)
        }
    }

    return p, nil
}

func main() {
    p, err := helper(ChildA{"hello"}, ChildB{"world"}, ChildC{})
    if err != nil {
        panic(err)
    }

    fmt.Println(p)
}

You can use Visitor pattern.

type Parent struct {
    A ChildA
    B ChildB
    C ChildC
}

type Child interface {
    VisitParent(*Parent)
}

type ChildA struct{}

func (c ChildA) VisitParent(parent *Parent) {
    parent.A = c
}

type ChildB struct{}

func (c ChildB) VisitParent(parent *Parent) {
    parent.B = c
}

type ChildC struct{}

func (c ChildC) VisitParent(parent *Parent) {
    parent.C = c
}

func SomeHelper(someChild Child) Parent {
    parent := Parent{}
    someChild.VisitParent(&parent)

    return parent
}
Related