我有一个包含类似
1,2,3
之类的变量。这些实际上是三个值,我想在三个变量中使用它们,称为 v1
、v2
、v3
(但不是在数组中)。
现在我正在按以下方式执行此操作:
tmp := strings.Split(*w, ",")
sw, _ := strconv.Atoi(tmp[0])
rw, _ := strconv.Atoi(tmp[1])
pw, _ := strconv.Atoi(tmp[2])
这是可行的,尽管它非常重复并且在 Go 中感觉不正确。
解决这个问题的更干净的方法是什么?
以特定格式从
string
中解析数据并将解析后的值存储到变量中是一项完美的任务,并且使用 fmt.Sscanf()
可以轻松完成:
src := "1,2,3"
var a, b, c int
parsed, err := fmt.Sscanf(src, "%d,%d,%d", &a, &b, &c)
fmt.Println(parsed, err, a, b, c)
输出(在Go Playground上尝试一下):
3 <nil> 1 2 3
如上所述,这是非常宽松的,并且还将成功解析
"1,2,3,"
和 "1,2,3,4"
输入。这可能是也可能不是问题(取决于您的情况)。如果你想严格一点,可以应用这个小技巧:
var temp int
parsed, err := fmt.Sscanf(src+",1", "%d,%d,%d,%d", &a, &b, &c, &temp)
我们所做的是再追加一个与输入匹配的数字。如果原始输入不以数字结尾(例如
"1,2,3,"
),则解析将失败并出现非nil
错误,上面的示例给出:
3 expected integer 1 2 3
在Go Playground上尝试一下。当然,它会继续解析“有效”输入,不会出现任何错误。
请注意,这仍然接受输入
"1,2,3,4"
。我们可以将这个技巧“减少”为单个字符,并且我们不一定需要一个“目标”变量来存储它,它可以简单地由格式字符串指定,如本例所示:
parsed, err := fmt.Sscanf(src+"~", "%d,%d,%d~", &a, &b, &c)
我们在输入中附加了一个“不太可能”出现的特殊字符,并且我们期望在格式字符串中出现该特殊字符。尝试解析无效输入(例如 "1,2,3,"
或
"1,2,3,4"
)将导致错误,例如:3 input does not match format 1 2 3
在Go Playground
V = make(map[int]int)
// in cycle
for i :=1; i < 3; i ++ {
V[i], _ = strconv.AtoI(tmp[i])
}