dictionary - 是 "bad form"在一条语句中进行map lookup和type assertion吗?

标签 dictionary go idioms type-assertion

我刚刚意识到可以在一条语句中执行映射查找和类型/接口(interface)断言。

m := map[string]interface{}{
    "key": "the value",
}
if value, ok := m["key"].(string); ok {
    fmt.Printf("value exists and is a string: %s\n", value)
} else {
    fmt.Println("value does not exist or is not a string")
}

这被认为是不好的吗? 我还没有看到任何官方文档对此发表评论。

编辑:我知道这段代码无法区分“键不存在”和“值类型不正确”。

edit2:咳咳,else 子句中的打印不正确:(

最佳答案

您所做的确实有效,因为您使用了 type assertion 的特殊逗号-ok 习语如果断言不成立,它不会 panic ,因为映射可以用不在其中的键索引(这将导致映射值类型的零值)。

的确,使用这个你无法判断键是否在映射中,或者它是但它的值为 nil,但你已经怀疑这一点就好像断言没有等等,你打印“值不存在或不是字符串”

要测试所有“角落”案例,请参阅此示例:

m := map[string]interface{}{
    "key":  "the value",
    "key2": 2,
    "key3": nil,
    // "key4":"", // Uncommented on purpose
}

for _, k := range []string{"key", "key2", "key3", "key4"} {
    if value, ok := m[k].(string); ok {
        fmt.Printf("[key: %s] value exists and is a string: %s\n", k, value)
    } else {
        fmt.Printf("[key: %s] value does not exist or is not a string: %s\n",
            k, value)
    }
}

输出(在 Go Playground 上尝试):

[key: key] value exists and is a string: the value
[key: key2] value does not exist or is not a string: 
[key: key3] value does not exist or is not a string: 
[key: key4] value does not exist or is not a string: 

所以基本上你可以使用它,它不会发生任何坏事(例如 panic 或内存泄漏),只需要知道它的限制(例如你无法获得与 关联的值“key2" 因为它不是 string 类型)。

如果您的目的是获取键的值(如果它存在且类型为 string),那么这正是您的代码所做的。尽管您应该避免在需要的地方使用数据结构和构造,因为在大型项目中更难理解和维护。

我的意思是,例如,如果在您的代码中的某个时刻,您希望键 "somekey" 具有关联的 string 值,但它没有,您不会立即知道为什么会这样;是因为映射不包含该键,还是因为它包含但具有错误类型的值(或者该值甚至可能是 nil)?需要进一步测试/调试以追查根本原因。

关于dictionary - 是 "bad form"在一条语句中进行map lookup和type assertion吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46300164/

相关文章:

用于设置核心亲和性的 C++ 风格?

arrays - 在 Smalltalk 的数组中检测 x 次相同对象的序列的惯用方法?

json - 创建用于 key 签名的有序 json 字符串

python - 通过 For 循环使用另一个 JSON 数据的 .append() 生成的列表

c++ - 定义一个内部有结构的 map

go - Go 语言中的副作用

go - 如何将一种数字类型的 slice 转换为另一种类型

arrays - 如何从嵌套数组返回值 - swift 3

go - 仅在 slice 的第一个元素上保留 unsafe.Pointer 并且没有对该 slice 本身的引用是否安全?

scala - Seq、SeqLike、GenSeq 还是 GenSeqLike?