我在Go中有一些结构体,它们实现了一个通用方法,因此我为此创建了一个接口(因为在某些方法中我需要接收接口类型的元素),基本上我有类似以下内容:

1
2
3
type Model interface {
    CommonMethod() string
}

然后,我有类似10的结构来实现该CommonMethod,例如:

1
2
3
4
5
6
7
type Contact struct {
    ...Some fields
}

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

直到这里一切都还好。然后,我有一个通用方法,该方法将接收2个Model实例,该函数的原型为:

1
func MyFunction(NewObject Model,PreviousObject Model)

在该函数中,我需要比较字段:两个对象之间的字段名称和值。我正在尝试使用Reflect进行设置,但是如果使用reflect.ValueOf(),我只会获取属性的值,而看不到任何获取名称的方法。因此,有没有一种方法可以获取Model接口中随附的结构,以便可以使用reflect.TypeOf()

如果我设置这个:

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

我收到此错误:
恐慌:反映:非结构类型的NumField

但是,如果我使用:

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

没有错误,但是我不能做类似NewObjectListing.Field(i).Name的事情

  • 我不明白,如果您可以呼叫reflect.ValueOf,则可以呼叫reflect.TypeOfValue.Type()。您可以举一个例子说明您在MyFunction中的实际操作吗?
  • @JimB嗨,我添加了更多信息
  • reflect.Value具有Type方法,但是我想知道在NewObject中传递的确切类型吗?
  • 无论您想做什么,都应该考虑向界面添加另一种方法。如果您接受接口,那是因为您需要接口。如果需要修改结构的属性,请改用结构,或在接口中添加方法以封装该逻辑。
  • @JimB的确切对象是一个Contact对象,该结构包含30个字段。我打印了接口,CommonMethod中的一切似乎都很好
  • 我有许多可以识别为Model实例的结构,Contacts,users,Games。因此,在CommonMethod中,我可以接收该实例的任何对象
  • @SrednyMCasanova:您需要提供一个最小的可复制示例。我不确定您在做什么,可以在值上获得NumField但不能从类型上获得,或者在哪里不能从Value调用Type
  • reflect.TypeOf()仅返回输入值的type,不带任何值
  • 您将无法仅从type获取任何字段
  • reflect.ValueOf()返回输入值的value
  • 如果从输入中获得的typestruct,则可以从输入值中获取一个numField,该值由reflect.ValueOf返回。
  • reflect.ValueOf(*).Field(n)返回结构的第(n + 1)个字段的值
  • 如果上面的方法没有任何帮助,请为上面的字段分配一个值。
  • 最好的方法是为输入结构的每个字段分配值

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

  • 如果要正确使用此方法,请将字段名从低位更改为标题一(您好->您好)
  • 如果reflect.ValueOf(*).Field(n).CanInterface()为true,则可以通过reflect.ValueOf(*).Field(n).Name()获得field n+1的名称