2

I'm trying to achieve the following:

Use-case:

  • I have three structures, I need to compare 2 of those against one. (in the example described as: a & b need to be compared against full)
  • Reflection is used to loop over every field, retrieve the name of the field. And comparing the difference between a & full, b & full, storing the results in a shared structure.
  • If the field equals World, we know it's a slice struct: I need to retrieve the first index of the Bar slice within the Foo structure. Even though the variable is a slice, I know it will always have a length of 1 in this use-case. When retrieved I need to loop over those fields, like what is happening in the previous if statement.

Example code:

type Foo struct {
    Hello string
    World []Bar
}

type Bar struct {
    Fish string
}

type Result struct {
    Field string

    Correct_A  bool
    Distance_A int

    Correct_B  bool
    Distance_B int

    Result []Result
}

func compare_structs() {
    var full, a, b Foo

    // filling in all variables...

    result := []Result{}

    rfx_f := reflect.ValueOf(full)
    rfx_a := reflect.ValueOf(a)
    rfx_b := reflect.ValueOf(b)

    type_result := rfx_f.Type()

    for i := 0; i < rfx_f.NumField(); i++ {
        tmp_res := Result{
            Field: type_result.Field(i).Name,
        }

        if reflect.TypeOf(full).Field(i).Type.Kind() != reflect.Slice {
            value := rfx_f.Field(i).Interface()
            value_a := rfx_a.FieldByName(tmp_res.Field).Interface()
            value_b := rfx_b.FieldByName(tmp_res.Field).Interface()

            // functions to compare the values of this field
            tmp_res.compare(value, value_a, value_b)
            tmp_res.lev(value, value_a, value_b)

            result = append(result, tmp_res)
        } else if tmp_res.Field == "World" {
            /*
                I need to retrieve the first index of the Bar slice within the Foo structure.
                Even though the variable is a slice, I know it will always have a length of 1 in this use-case.
                When retrieved I need to loop over those fields, like what is happening in the previous if statement.
            */
        }

    }
}

1 Answer 1

1

You first need to get the field:

wordField:=rfx_f.Field(i)

which you know to be a slice, so you index it to get the first element

item:=wordField.Index(0)

This will panic if index is out of range.

Then you can iterate the fields:

for fieldIx:=0;fieldIx<item.NumField();fieldIx++ {
    field:=item.Field(fieldIx)
}
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.