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

时间:2010-11-25 15:06:39

标签: string go type-conversion

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

5 个答案:

答案 0 :(得分:248)

例如,

package main

import (
    "flag"
    "fmt"
    "os"
    "strconv"
)

func main() {
    flag.Parse()
    s := flag.Arg(0)
    // string to int
    i, err := strconv.Atoi(s)
    if err != nil {
        // handle error
        fmt.Println(err)
        os.Exit(2)
    }
    fmt.Println(s, i)
}

答案 1 :(得分:50)

转换简单字符串

最简单的方法是使用strconv.Atoi()功能。

请注意,还有很多其他方法。例如,fmt.Sscan()strconv.ParseInt()提供了更大的灵活性,因为您可以指定base和bitsize。同样如strconv.Atoi()的文档中所述:

  

Atoi是ParseInt的缩写(s,10,0)。

以下是使用上述功能的示例(在Go Playground上试用):

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位数,如果更短则用零填充,这很容易解析如下:

s := "id:00123"

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

答案 2 :(得分:15)

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

  1. strconv.ParseInt(...)最快
  2. strconv.Atoi(...)仍然非常快
  3. fmt.Sscanf(...)不是非常快,但最灵活
  4. 这是一个显示每个功能的用法和示例时间的基准:

    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
    

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

尝试一下

import ("strconv")

value : = "123"
number,err := strconv.ParseUint(value, 10, 32)