Sredny M Casanova
Sredny M Casanova

Reputation: 5053

Reflect over Interface in Golang

I have some structs in Go, they implement a common method, so I created an interface for it (Because in some methods I need to receive an element of the type of the interface).Basically I have something like:

type Model interface {
    CommonMethod() string
}

Then I have something like 10 struct that implements that CommonMethod, for example:

type Contact struct {
    ...Some fields
}

func (Contact) CommonMethod() string {
    return "Something"
}

Until here everything is ok. Then I have a generic method that will receive 2 instances of Model, the proptotype for this function is:

func MyFunction(NewObject Model,PreviousObject Model)

In that function I need to compare the fields: name of the fields and values between the 2 objects. I am trying to make it using Reflect but if I use reflect.ValueOf() I only get the value of the attributes and I don't see any way to get the name. So, is there a way that I can get the struct that comes inside the Model interface so then I can use reflect.TypeOf()?

EDIT:

If I set this:

NewObjectListing := reflect.TypeOf(NewObject)
numFields := NewObjectListing.NumField()

I get this error: panic: reflect: NumField of non-struct type

But if I use:

NewObjectListing := reflect.ValueOf(NewObject)
numFields := NewObjectListing.NumField()

There is no error but then I cannot do things like NewObjectListing.Field(i).Name

Upvotes: 1

Views: 4591

Answers (1)

Nevercare
Nevercare

Reputation: 81

  1. reflect.TypeOf() just returns a type of the input value WITHOUT ANY VALUE
  2. you won't able to get any field from JUST a type
  3. reflect.ValueOf() returns the value of the input value
  4. if the type you got from the input is a struct, you'll be able to get a numField from the INPUT VALUE which returns by reflect.ValueOf.

  1. reflect.ValueOf(*).Field(n) returns the VALUE of the (n+1)th field of your struct
  2. if your got nothing from the method above, assign a value to the field above.
  3. the best way is to assign values to every field of your input struct

  4. reflect.TypeOf(*).Field(n).Name() returns the NAME of the (n+1)th field.

  5. if you want to correctly use this method, change your field name from a lower one to title one(hello -> Hello)
  6. if reflect.ValueOf(*).Field(n).CanInterface() is true, your can get your field n+1's name by reflect.ValueOf(*).Field(n).Name()

Upvotes: 2

Related Questions