在Golang中反射接口

huangapple go评论72阅读模式
英文:

Reflect over Interface in Golang

问题

我在Go语言中有一些结构体,它们实现了一个共同的方法,所以我为它创建了一个接口(因为在某些方法中,我需要接收接口类型的元素)。基本上,我有如下代码:

type Model interface {
    CommonMethod() string
}

type Contact struct {
    // 一些字段
}

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

到这里一切都好。然后我有一个通用方法,它将接收两个Model的实例,该函数的原型如下:

func MyFunction(NewObject Model, PreviousObject Model)

在这个函数中,我需要比较两个对象之间的字段:字段的名称和值。我尝试使用reflect来实现,但是如果我使用reflect.ValueOf(),我只能获取属性的值,而无法获取名称。那么,有没有办法可以获取Model接口中的结构体,然后我就可以使用reflect.TypeOf()了呢?

编辑:

如果我这样设置:

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

我会得到以下错误:

panic: reflect: NumField of non-struct type

但是如果我使用:

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

就不会出错,但是我无法像这样做:NewObjectListing.Field(i).Name

英文:

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

得分: 2

  1. reflect.TypeOf()只返回输入值的type,没有任何值。
  2. 你无法仅通过type获取任何字段。
  3. reflect.ValueOf()返回输入值的value
  4. 如果你从输入中得到的type是一个struct,你将能够从reflect.ValueOf返回的INPUT VALUE中获取numField。

  1. reflect.ValueOf(*).Field(n)返回你的结构体的第(n+1)个字段的VALUE。

  2. 如果上述方法没有得到任何结果,请给上面的字段赋一个值。

  3. 最好的方法是给你的输入结构体的每个字段赋值。

  4. reflect.TypeOf(*).Field(n).Name()返回第(n+1)个字段的名称。

  5. 如果你想正确使用这个方法,请将字段名称从小写改为大写(hello -> Hello)。

  6. 如果reflect.ValueOf(*).Field(n).CanInterface()为true,你可以通过reflect.ValueOf(*).Field(n).Name()获取第n+1个字段的名称。

英文:
  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()

huangapple
  • 本文由 发表于 2017年7月7日 23:31:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/44974621.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定