Go 如何使用fmt.Sscan将整数解析为数组?
我试图将字符串中的整数列表扫描到一个数组(或者一个切片) 我需要将什么作为第二个参数传递给Go 如何使用fmt.Sscan将整数解析为数组?,go,Go,我试图将字符串中的整数列表扫描到一个数组(或者一个切片) 我需要将什么作为第二个参数传递给Sscan,才能使其工作 我知道我可以通过nums[0]、nums[1]…等,但我更喜欢一个参数。我认为这不可能是一个方便的单行程序。由于Sscan采用…接口{},因此您还需要传递接口片,因此首先转换数组: func main() { var nums [5]int // Convert to interfaces xnums := make([]interface{}, len(
Sscan
,才能使其工作
我知道我可以通过
nums[0]、nums[1]…
等,但我更喜欢一个参数。我认为这不可能是一个方便的单行程序。由于Sscan
采用…接口{}
,因此您还需要传递接口片,因此首先转换数组:
func main() {
var nums [5]int
// Convert to interfaces
xnums := make([]interface{}, len(nums))
for n := range nums {
xnums[n] = &nums[n]
}
n, err := fmt.Sscan("1 2 3 4 5", xnums...)
if err != nil {
fmt.Printf("field %d: %s\n", n+1, err)
}
fmt.Println(nums)
}
显然,您可以在接口数组中混合不同的类型,这样可以更容易地扫描更复杂的字符串。对于仅限空间的整数,最好使用
strings.Split
或bufio.Scanner
以及strconv.Atoi来处理不仅仅是硬编码的字符串,可能最好使用,和一个接口来完成:
package main
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
func scanInts(r io.Reader) ([]int, error) {
s := bufio.NewScanner(r)
s.Split(bufio.ScanWords)
var ints []int
for s.Scan() {
i, err := strconv.Atoi(s.Text())
if err != nil {
return ints, err
}
ints = append(ints, i)
}
return ints, s.Err()
}
func main() {
input := "1 2 3 4 5"
ints, err := scanInts(strings.NewReader(input))
if err != nil {
fmt.Println(err)
}
fmt.Println(ints)
}
产生:
[1 2 3 4 5]
除非您试图专门使用Sscann,否则您也可以尝试以下替代方法:
- 按空格分割输入字符串
- 迭代生成的数组
- 将每个字符串转换为int
- 将结果值存储到int切片中
像这样:
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
nums := make([]int, 0)
for _, s := range strings.Split("1 2 3 4 5", " ") {
i, e := strconv.Atoi(s)
if e != nil {
i = 0 // that was not a number, default to 0
}
nums = append(nums, i)
}
fmt.Println(nums)
}
看看我喜欢这个答案,它巧妙地使用了Sscan的反射。您可以将var nums[5]int
更改为var nums[5]string
并且它仍然有效:-)。此外,它还为愚蠢的输入返回某种合理的值!看见唯一的问题可能是当输入[5]int
时,对无效输入使用0
<因此,可能建议使用code>strconv.Atoi
。@Intermernet,您显然在Sccan
中仍有错误检查,我真的应该检查我答案中返回的错误。查看您的修改示例:[更新了我的答案以反映这一点!]是的,我很挑剔:-)我从您的答案中学到了一条很好的捷径,再次感谢!非常感谢。对于我的简单用例来说,这看起来有点太复杂了,但我学到了一些新东西(正如你可能已经从问题中猜到的那样,go仍处于初级阶段)。@Johannesharra没问题,你可能需要记住的重要一点是,字符串可能不仅仅包含整数,您的代码需要考虑到这一点strconv.Atoi
将检查下一个“东西”是否可以转换为整数,如果不能转换,则返回错误。你应该使用它,不管你最终采用什么解决方案。可能是最简单的解决方案,我已经知道了,但试图进一步简化。谢谢
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
nums := make([]int, 0)
for _, s := range strings.Split("1 2 3 4 5", " ") {
i, e := strconv.Atoi(s)
if e != nil {
i = 0 // that was not a number, default to 0
}
nums = append(nums, i)
}
fmt.Println(nums)
}