改善多个地图访问并避免不正确的类型转换

时间:2015-07-16 18:19:35

标签: go

我的项目中有这个代码:

//data.Objects is a map[string]interface{}
corporateName := data.Objects["corporateName"].(string)
dba := data.Objects["dba"].(string)
licence := data.Objects["licence"].(string)
resaleCert := data.Objects["resaleCert"].(string)
einNumber := data.Objects["einNumber"].(string)
phoneNumber := data.Objects["phoneNumber"].(string)
website := data.Objects["website"].(string)
contactName := data.Objects["contactName"].(string)
email := data.Objects["email"].(string)
billingAddress := data.Objects["billingStreet"].(string)
billingCity := data.Objects["billingCity"].(string)
billingCode := data.Objects["billingCode"].(int64)
billingState := data.Objects["billingState"].(string)
billingCountry := data.Objects["billingContry"].(string)
deliveryAddress := data.Objects["deliveryAddress"].(string)

在声明的地图中,其中一些键无法关联,因此可以返回 nil 。如果他们这样做,我就无法进行类型转换。 我正在寻找一种方法来改善此访问并防止错误的转换。

使用if if来检查它是非常烦人和冗长的。有没有办法避免它?

N.B。 在这种情况下,结构的 nil 值是完全合法的,所以它不是我以前可以避免的问题。

2 个答案:

答案 0 :(得分:1)

@JimB 所述,您可以使用自定义类型,例如

type detailsMap map[string]interface{}

func (dm detailsMap) String(key string) string {
    if val, ok := dm[key].(string); ok {
        return val
    }
    return ""
}

func (dm detailsMap) Int64(key string) int64 {
    if val, ok := dm[key].(int64); ok {
        return val
    }
    return 0
}

请注意,如果类型的基础key中不存在所需的map[string]interface{},则会返回默认zero values

如果您无法控制原始data.Objects,则可以通过detailsMap将其转换为detailsMap(data.Objects)

然后您可以按如下方式获取值:

corporateName := dm.String("corporateName")
website := dm.String("website")
billingCode := dm.Int64("billingCode")

Here是操场上的一个例子。

答案 1 :(得分:-1)

如果您发现重复的if-else烦人(您应该,我同意),请创建一个新功能来帮助管理它。

编写一个本地interfaceToString(i *interface) string方法,如果地图对象为nil则返回nil,否则返回转换为字符串的对象。你可以在那里放置一个if语句,并使该函数不受代码的限制。

然后只需在地图的每个返回元素上调用该函数,而不是直接将其强制转换。