1
votes

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

1
I don't understand, if you can call reflect.ValueOf you can call reflect.TypeOf or Value.Type(). Can you show an example of what you're actually doing in MyFunction? - JimB
@JimB Hi, I added more info - Sredny M Casanova
A reflect.Value has a Type method, but I'm curious as to the exact type being passed in a NewObject? - JimB
You should consider adding another method to your interface for whatever you're trying to do. If you're accepting an interface, it's because you need an interface. If you need to modify properties on a struct, then accept a struct instead, or add a method to the interface that will encapsulate that logic. - Gavin
@JimB the exact object is a Contact object, that struct contains 30 fields. I printedn the interface and everything seems to be fine in the CommonMethod - Sredny M Casanova

1 Answers

2
votes
  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()