在Go中转换字符串为整数类型?

我正在尝试将从flag.Arg(n)返回的字符串转换为int。在围棋中做这件事的惯用方法是什么?

461184 次浏览

例如strconv.Atoi

代码:

package main


import (
"fmt"
"strconv"
)


func main() {
s := "123"


// string to int
i, err := strconv.Atoi(s)
if err != nil {
// ... handle error
panic(err)
}


fmt.Println(s, i)
}

转换简单字符串

最简单的方法是使用strconv.Atoi()函数。

请注意,还有许多其他方法。例如fmt.Sscan()strconv.ParseInt(),它们提供了更大的灵活性,例如,你可以指定基数和位大小。同样如strconv.Atoi()的文档中所述:

Atoi等价于ParseInt(s, 10,0),转换为int类型。

下面是一个使用上述函数的示例(在去操场上尝试它):

flag.Parse()
s := flag.Arg(0)


if i, err := strconv.Atoi(s); err == nil {
fmt.Printf("i=%d, type: %T\n", i, i)
}


if i, err := strconv.ParseInt(s, 10, 64); err == nil {
fmt.Printf("i=%d, type: %T\n", i, i)
}


var i int
if _, err := fmt.Sscan(s, &i); err == nil {
fmt.Printf("i=%d, type: %T\n", i, i)
}

输出(如果用参数"123"调用):

i=123, type: int
i=123, type: int64
i=123, type: int

解析自定义字符串

还有一个方便的fmt.Sscanf(),它提供了更大的灵活性,因为你可以在输入string中指定数字格式(如宽度,基数等)以及额外的字符。

这对于解析包含数字的自定义字符串非常有用。例如,如果你的输入以"id:00123"的形式提供,其中你有一个前缀"id:",数字是固定的5位数字,如果更短,则用0填充,这很容易像这样解析:

s := "id:00123"


var i int
if _, err := fmt.Sscanf(s, "id:%5d", &i); err == nil {
fmt.Println(i) // Outputs 123
}

以下是将字符串解析为整数的三种方法,从最快运行时到最慢运行时:

  1. strconv.ParseInt(...)最快
  2. strconv.Atoi(...)仍然非常快
  3. fmt.Sscanf(...)不是特别快,但非常灵活

下面是一个基准测试,显示了每个函数的使用情况和示例计时:

package main


import "fmt"
import "strconv"
import "testing"


var num = 123456
var numstr = "123456"


func BenchmarkStrconvParseInt(b *testing.B) {
num64 := int64(num)
for i := 0; i < b.N; i++ {
x, err := strconv.ParseInt(numstr, 10, 64)
if x != num64 || err != nil {
b.Error(err)
}
}
}


func BenchmarkAtoi(b *testing.B) {
for i := 0; i < b.N; i++ {
x, err := strconv.Atoi(numstr)
if x != num || err != nil {
b.Error(err)
}
}
}


func BenchmarkFmtSscan(b *testing.B) {
for i := 0; i < b.N; i++ {
var x int
n, err := fmt.Sscanf(numstr, "%d", &x)
if n != 1 || x != num || err != nil {
b.Error(err)
}
}
}

你可以通过保存为atoi_test.go并运行go test -bench=. atoi_test.go来运行它。

goos: darwin
goarch: amd64
BenchmarkStrconvParseInt-8      100000000           17.1 ns/op
BenchmarkAtoi-8                 100000000           19.4 ns/op
BenchmarkFmtSscan-8               2000000          693   ns/op
PASS
ok      command-line-arguments  5.797s

如果控制输入数据,则可以使用迷你版本

package main


import (
"testing"
"strconv"
)


func Atoi (s string) int {
var (
n uint64
i int
v byte
)
for ; i < len(s); i++ {
d := s[i]
if '0' <= d && d <= '9' {
v = d - '0'
} else if 'a' <= d && d <= 'z' {
v = d - 'a' + 10
} else if 'A' <= d && d <= 'Z' {
v = d - 'A' + 10
} else {
n = 0; break
}
n *= uint64(10)
n += uint64(v)
}
return int(n)
}


func BenchmarkAtoi(b *testing.B) {
for i := 0; i < b.N; i++ {
in := Atoi("9999")
_ = in
}
}


func BenchmarkStrconvAtoi(b *testing.B) {
for i := 0; i < b.N; i++ {
in, _ := strconv.Atoi("9999")
_ = in
}
}

最快的选择(如有必要,请开支票)。结果:

Path>go test -bench=. atoi_test.go
goos: windows
goarch: amd64
BenchmarkAtoi-2                 100000000               14.6 ns/op
BenchmarkStrconvAtoi-2          30000000                51.2 ns/op
PASS
ok      path     3.293s

试试这个

import ("strconv")


value := "123"
number,err := strconv.ParseUint(value, 10, 32)
finalIntNum := int(number) //Convert uint64 To int