首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >terraform提供者中TypeList的类型断言

terraform提供者中TypeList的类型断言
EN

Stack Overflow用户
提问于 2020-01-13 09:59:42
回答 1查看 1.3K关注 0票数 2

我正在编写一个Terraform,并且当我有一个包含TypeList元素的TypeString时,我试图找出进行类型断言的最佳方法。

资源的定义如下:

代码语言:javascript
复制
    return &schema.Resource{
        Create: resourceConfigObjectCreate,
        Read:   resourceConfigObjectRead,
        Update: resourceConfigObjectUpdate,
        Delete: resourceConfigObjectDelete,

        Schema: map[string]*schema.Schema{
            "name": &schema.Schema{
                Type:     schema.TypeString,
                Required: true,
            },
            "notification_options": &schema.Schema{
                Type:     schema.TypeList,
                Optional: true,
                Elem: schema.Schema{
                    Type:             schema.TypeString,
                },
            },
        },
    }
}

我希望将这些值加载到这样定义的自定义类型中:

代码语言:javascript
复制
type ConfigObject struct {
    Name                        string   `json:"name,omitempty"`
    NotificationOptions         []string `json:"notification_options,omitempty"`

}

因为schema.ResourceData.Get返回一个接口{},所以需要类型断言。

代码语言:javascript
复制
    item := thruk.ConfigObject{
        Name: schema.ResourceData.Get("name").(string),
        NotificationOptions: extractSliceOfStrings(schema.ResourceData.Get("notification_options")),
    }

对于字符串,我做得很容易,但是字符串的片段更复杂,我创建了以下函数:

代码语言:javascript
复制
func extractSliceOfStrings(i interface{}) (slice []string) {
    s := reflect.ValueOf(i)
    if !s.IsValid() {
        return
    }
    for i := 0; i < s.Len(); i++ {
        slice = append(slice, s.Index(i).String())
    }
    return
}

这是正确的做法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-14 18:54:44

在Terraform中使用ResourceData API时,了解哪种Go类型对应于每一种模式类型是很有帮助的。您已经推断出schema.TypeString对应于string。下面是一个完整的列表:

  • TypeBoolbool
  • TypeStringstring
  • TypeIntint
  • TypeList[]interface{}
  • TypeMapmap[string]interface{}
  • TypeSet*schema.Set
  • Elem设置为*schema.Resourcemap[string]interface{}时,元素类型

上面的翻译记录在SDK的模式类型文档页面中,在每个标题下作为“数据结构:”。

每当您处理集合时,从Go的角度来看,元素类型总是interface{},以反映元素类型直到运行时才决定这一事实。但是,上面定义的映射规则也适用于这些元素值,因此,要转换TypeListElemTypeString,首先要断言片类型,然后依次断言每个元素:

代码语言:javascript
复制
itemsRaw := d.Get("example").([]interface{})
items := make([]string, len(itemsRaw))
for i, raw := range itemsRaw {
    items[i] = raw.(string)
}

不幸的是,由于go接口和类型断言的设计,无法在一个步骤中直接从[]interface{}[]string

您可以对TypeMap采取类似的方法,如果您最终需要map[string]string

代码语言:javascript
复制
itemsRaw := d.Get("example").(map[string]interface{})
items := make(map[string]string, len(itemsRaw))
for k, raw := range itemsRaw {
    items[k] = raw.(string)
}

由于自定义的TypeSet容器,*schema.Set稍微复杂一些,但是您可以调用集合的List方法来获得一个[]interface{},然后您可以将其与上面的TypeList处理相同:

代码语言:javascript
复制
itemsRaw := d.Get("example").(*schema.Set).List()
items := make([]string, len(itemsRaw))
for i, raw := range itemsRaw {
    items[i] = raw.(string)
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59714262

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档