我正在编写一个Terraform,并且当我有一个包含TypeList元素的TypeString时,我试图找出进行类型断言的最佳方法。
资源的定义如下:
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,
},
},
},
}
}我希望将这些值加载到这样定义的自定义类型中:
type ConfigObject struct {
Name string `json:"name,omitempty"`
NotificationOptions []string `json:"notification_options,omitempty"`
}因为schema.ResourceData.Get返回一个接口{},所以需要类型断言。
item := thruk.ConfigObject{
Name: schema.ResourceData.Get("name").(string),
NotificationOptions: extractSliceOfStrings(schema.ResourceData.Get("notification_options")),
}对于字符串,我做得很容易,但是字符串的片段更复杂,我创建了以下函数:
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
}这是正确的做法吗?
发布于 2020-01-14 18:54:44
在Terraform中使用ResourceData API时,了解哪种Go类型对应于每一种模式类型是很有帮助的。您已经推断出schema.TypeString对应于string。下面是一个完整的列表:
TypeBool⇒boolTypeString⇒stringTypeInt⇒intTypeList⇒[]interface{}TypeMap⇒map[string]interface{}TypeSet⇒*schema.SetElem设置为*schema.Resource:map[string]interface{}时,元素类型上面的翻译记录在SDK的模式类型文档页面中,在每个标题下作为“数据结构:”。
每当您处理集合时,从Go的角度来看,元素类型总是interface{},以反映元素类型直到运行时才决定这一事实。但是,上面定义的映射规则也适用于这些元素值,因此,要转换TypeList的Elem是TypeString,首先要断言片类型,然后依次断言每个元素:
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
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处理相同:
itemsRaw := d.Get("example").(*schema.Set).List()
items := make([]string, len(itemsRaw))
for i, raw := range itemsRaw {
items[i] = raw.(string)
}https://stackoverflow.com/questions/59714262
复制相似问题