【问题标题】: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 情况?

【问题讨论】:

标签: go


【解决方案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"),
}

【讨论】:

    猜你喜欢
    • 2013-01-21
    • 2023-04-10
    • 2020-01-25
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多