处理映射中的nil值

  • 本文关键字:nil 映射 处理 go
  • 更新时间 :
  • 英文 :


我想用map中的值创建一个结构体

下面是一个片段:

log := &Log{
Facility:  parts["facility"].(int),
Severity:  parts["severity"].(int),
Timestamp: parts["timestamp"].(time.Time),
Hostname:  parts["hostname"].(string),
AppName:   parts["appName"].(string),
Client:    parts["client"].(string),
Priority:  parts["priority"].(int),
Message:   parts["message"].(string),
}

问题是,如果其中一个值为nil,就会发生恐慌。所以我想这样做:

Facility:  parts["facility"] != nil ? parts["facility"].(int) : 0

但是这不是一个有效的语法。

我必须单独检查每个键来处理nil情况吗?

你可以这样做:

log := &Log{}
log.Facility, _ = parts["facility"].(int)
log.Severity, _ = parts["severity"].(int)
...

这将使用类型断言的双值形式,其中第二个值指示类型断言是否有效,然后忽略该值,因此,如果映射不包含键,或者键不是所需的类型,则使用零值初始化struct成员。

如果您愿意,可以为这些类型编写包装器:

func toInt(x interface{}) int {
if i, ok := x.(int); ok {
return i
}
return 0 // Or what you would like to have as a default.
}

如果您想使用类型的默认值,可以缩短

func toInt(x interface{}) int {
i, _ := x.(int)
return i
}

将使它看起来像这样:

log := &Log{
Facility:  toInt(parts["facility"]),
Severity:  toInt(parts["severity"]),
Timestamp: toTime(parts["timestamp"]),
Hostname:  toString(parts["hostname"]),
AppName:   toString(parts["appName"]),
Client:    toString(parts["client"]),
Priority:  toInt(parts["priority"]),
Message:   toString(parts["message"]),
}

你可以更进一步,在本地编写你的转换函数:

var parts map[string]interface{}
// ...
i := func(name string) int {
i, _ := parts[name].(int)
return i
}
s := func(name string) string {
s, _ := parts[name].(string)
return s
}
t := func(name string) time.Time {
t, _ := parts[name].(time.Time)
return t
}
log := &Log{
Facility:  i("facility"),
Severity:  i("severity"),
Timestamp: t("timestamp"),
Hostname:  s("hostname"),
AppName:   s("appName"),
Client:    s("client"),
Priority:  i("priority"),
Message:   s("message"),
}

最新更新