处理地图中的零值
Posted
技术标签:
【中文标题】处理地图中的零值【英文标题】:Handling nil values in a map 【发布时间】:2021-06-05 16:27:21 【问题描述】:我想用地图中的值创建一个结构。
这是一个sn-p:
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 情况?
【问题讨论】:
1>如果事先知道数据类型,那么您必须使用结构或结构映射 2> data,ok:=parts["facility"]; if ok && data!=nil value=data.(int) golang.org/doc/faq#Does_Go_have_a_ternary_form 见What is the idiomatic Go equivalent of C's ternary operator? 【参考方案1】:你可以这样做:
log := &Log
log.Facility, _ = parts["facility"].(int)
log.Severity, _ = parts["severity"].(int)
...
这将使用类型断言的双值形式,其中第二个值指示类型断言是否有效,然后您将忽略该值,因此如果映射没有,则使用零值初始化结构成员包含密钥,或者如果密钥不是所需的类型。
【讨论】:
从技术上讲,这是类型断言的 2 值形式,而不是映射查找。映射中的 nil 接口值被传递给断言,然后断言可以将接口断言为所需的零值。 @JimB,你是对的我修正了答案【参考方案2】:如果您愿意,可以为这些类型编写包装器:
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"),
【讨论】:
以上是关于处理地图中的零值的主要内容,如果未能解决你的问题,请参考以下文章