【问题标题】:Reflect showing different a different type than error反映显示与错误不同的类型
【发布时间】:2018-10-11 05:07:10
【问题描述】:

背景:我使用 govmomi 为 vmware 收集配置。我目前正在获取所需的数据存储信息。我需要的字段之一是磁盘 Naa。这可以在 Vmfs 字段下的 VmfsDatastoreInfo 结构中找到。

问题:我正在循环一个范围,并且我认为 Ds.Info 属于 VmfsDatastoreInfo 类型,因此理论上我可以通过 Ds.Info.Vmfs 获得所需的信息。当我引用这个时,我得到了错误:

ds.Info.Vmfs undefined (type types.BaseDatastoreInfo has no field or method Vmfs)

出于好奇,我探索了使用反射并做了以下工作:

fmt.Println(reflect.TypeOf(ds.Info))

输出是

*types.VmfsDatastoreInfo

我试图理解为什么同一个对象显示为两种不同的类型?

编辑: 到达 ds:

c, err := govmomi.NewClient(ctx, u, true)

//Check if the connection was successful
if err != nil {
    fmt.Println(err)
}

// Create view of Datastore objects
m := view.NewManager(c.Client)

d, _ := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, []string{"Datastore"}, true)



if err != nil {
    log.Fatal(err)
}

defer d.Destroy(ctx)

//Retrieve a list of all Virtual Machines including their summary and runtime
var dss []mo.Datastore
err = d.Retrieve(ctx, []string{"Datastore"}, []string{"info", "host"}, &dss)
if err != nil {
    log.Fatal(err)
}


for _, ds := range dss {
    fmt.Println(reflect.TypeOf(ds.Info))
    s := reflect.ValueOf(ds.Info).Elem()

    typeOfT := s.Type()

    for i := 0; i < s.NumField(); i++ {

    f := s.Field(i)

    fmt.Println(i, typeOfT.Field(i).Name, f.Type(), f.Interface())

    }

}

ds 是一种数据存储类型:

type Datastore struct {
    ManagedEntity

    Info              types.BaseDatastoreInfo        `mo:"info"`
    Summary           types.DatastoreSummary         `mo:"summary"`
    Host              []types.DatastoreHostMount     `mo:"host"`
    Vm                []types.ManagedObjectReference `mo:"vm"`
    Browser           types.ManagedObjectReference   `mo:"browser"`
    Capability        types.DatastoreCapability      `mo:"capability"`
    IormConfiguration *types.StorageIORMInfo         `mo:"iormConfiguration"`
}

通过 Govmomi 包信息,我发现了以下内容

type BaseDatastoreInfo interface {
    GetDatastoreInfo() *DatastoreInfo
}

func (b *DatastoreInfo) GetDatastoreInfo() *DatastoreInfo

type DatastoreInfo struct {
    DynamicData

    Name                   string     `xml:"name"`
    Url                    string     `xml:"url"`
    FreeSpace              int64      `xml:"freeSpace"`
    MaxFileSize            int64      `xml:"maxFileSize"`
    MaxVirtualDiskCapacity int64      `xml:"maxVirtualDiskCapacity,omitempty"`
    MaxMemoryFileSize      int64      `xml:"maxMemoryFileSize,omitempty"`
    Timestamp              *time.Time `xml:"timestamp"`
    ContainerId            string     `xml:"containerId,omitempty"`
}

Govmomi Struct Info

【问题讨论】:

  • 什么是ds?您必须提供相关代码和所有类型,或者您应该链接到相关内容。您不能指望其他人深入研究该文档。
  • @Volker 添加了我认为您需要的信息。如果我错过了什么,请告诉我

标签: go reflection vmware govmomi


【解决方案1】:

我试图理解为什么同一个对象显示为两种不同的类型?

不是。

我认为 Ds.Info 属于 VmfsDatastoreInfo 类型

没有。如果dsDatastore,则ds.InfoBaseDatastoreInfo 类型,这是一个接口,因此只有一个方法GetDatastoreInfo()。这就是您看到错误的原因

ds.Info.Vmfs undefined (type types.BaseDatastoreInfo has no field or method Vmfs)

现在阅读 package reflect 的整个包文档和 reflect.TypoOf 的文档。现在阅读https://blog.golang.org/laws-of-reflection

您的reflect.TypeOf(ds.Info) 解析ds.Info 的动态类型(其静态类型为BaseDatastoreInfo)。一个简单的例子见https://play.golang.org/p/kgDYXv4i63Treflect.TypeOf 看起来 inside 它的论点(即interface {});如果不报告,则始终报告静态类型,则 reflect.TypeOf 将始终报告 interface{})。

也许你应该只使用没有反射的接口:

ds.Info.GetDatastoreInfo()

并使用该信息。此处无需赘述。

【讨论】:

  • 为此干杯,我是 Go 新手,但我想我明白了。
猜你喜欢
  • 2011-12-23
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多