Dictionary 测试和处理地图中多个键的惯用方式是什么?
我有一个Dictionary 测试和处理地图中多个键的惯用方式是什么?,dictionary,go,Dictionary,Go,我有一个map[string]string,我需要测试一些键是否存在,如果存在,将一些值转换为整数。例如: m := map[string]string{"a": "b", "c": "d", "e": "f"} if v1, ok := m["a"]; ok { if v2, ok := m["c"]; ok { if i1, err := strconv.Atoi(v1); err != nil { if i2, err := strconv.Atoi(v2);
map[string]string
,我需要测试一些键是否存在,如果存在,将一些值转换为整数。例如:
m := map[string]string{"a": "b", "c": "d", "e": "f"}
if v1, ok := m["a"]; ok {
if v2, ok := m["c"]; ok {
if i1, err := strconv.Atoi(v1); err != nil {
if i2, err := strconv.Atoi(v2); err != nil {
// do something with i1, i2
}
}
}
}
fmt.Println("a exists:\t", m2.exists("a"))
fmt.Println("asd exists:\t", m2.exists("asd"))
fmt.Println("a isInt:\t", m2.isInt("a"))
fmt.Println("c isInt:\t", m2.isInt("c"))
我发现自己的思路是:
if m.exists("a") && m.exists("c") && is_int(m["a"]) && is_int(m["c"]) {
// do something with atoi(m["a"]) and atoi(m["c"])
}
。。。但使用Go的标准库并不方便。那么,怎么做呢?一种方法是创建自己的
map[string]string
类型并添加一些简单的方法。下面是一个简单的例子:
type mapExists map[string]string
func (m mapExists) exists(key string) bool {
_, ok := m[key]
return ok
}
func (m mapExists) isInt(key string) bool {
v, ok := m[key]
if !ok {
return false
}
_, err := strconv.ParseInt(v, 10, 64)
return err == nil
}
您可以使用以下命令将map[string]字符串
转换为map exists
:
m := map[string]string{
"a": "b",
"c": "2",
}
m2 := mapExists(m)
然后调用示例中的内容:
m := map[string]string{"a": "b", "c": "d", "e": "f"}
if v1, ok := m["a"]; ok {
if v2, ok := m["c"]; ok {
if i1, err := strconv.Atoi(v1); err != nil {
if i2, err := strconv.Atoi(v2); err != nil {
// do something with i1, i2
}
}
}
}
fmt.Println("a exists:\t", m2.exists("a"))
fmt.Println("asd exists:\t", m2.exists("asd"))
fmt.Println("a isInt:\t", m2.isInt("a"))
fmt.Println("c isInt:\t", m2.isInt("c"))
这将输出:
a exists: true
asd exists: false
a isInt: false
c isInt: true
这是“最好的”还是“惯用的”方式,取决于具体情况,取决于观点。一般来说,我(个人)宁愿不使用这些包装。您的上述示例可以改写为以下内容:
func test() {
m := map[string]string{"a": "b", "c": "d", "e": "f"}
v1, v1ok := m["a"]
v2, v2ok := m["c"]
if !v1ok || !v2ok {
return
}
i1, err := strconv.Atoi(v1)
if err != nil {
return
}
i2, err := strconv.Atoi(v2) {
if err != nil {
return
}
}
我认为这更具可读性。它更冗长,但Go是一种冗长的语言;-)
但同样,这取决于整个代码库。如果您经常调用此模式,则自定义类型可能是一个很好的解决方案(代价是性能稍低,这可能是问题,也可能不是问题)。测试
字符串是否是数字,并将其转换为数字的工作量基本相同
因此,我宁愿使用下面的util函数,它除了检查键和测试值之外,还返回转换后的数字:
func getInts(m map[string]string, keys ...string) (is []int, err error) {
for _, k := range keys {
v, ok := m[k]
if !ok {
return is, fmt.Errorf("%s is missing", k)
}
var i int
if i, err = strconv.Atoi(v); err != nil {
return
}
is = append(is, i)
}
return
}
使用3种不同的情况对其进行测试:
maps := []map[string]string{
{},
{"a": "b", "c": "d", "e": "f"},
{"a": "1", "c": "2", "e": "f"},
}
for _, m := range maps {
if is, err := getInts(m, "a", "c"); err == nil {
fmt.Println("Numbers:", is)
} else {
fmt.Println("Error:", err)
}
}
输出(在上尝试):