【问题标题】:Convert string to integer type in Go?在 Go 中将字符串转换为整数类型?
【发布时间】:2011-05-15 18:33:21
【问题描述】:

我正在尝试将从flag.Arg(n) 返回的字符串转换为int。在 Go 中执行此操作的惯用方式是什么?

【问题讨论】:

标签: string go type-conversion


【解决方案1】:

例如,

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)
}

【讨论】:

  • 或者只是做一个致命的,例如panic(err)
  • 你为什么要用不必要的东西,flag os 和 bs 让它变得复杂
  • strconv 同样可以解释为 String ConvertAtoi 有什么含义(扩展名)以便于记忆。
  • @RoshanaPitigala "A" 在 A-to-Z 中表示由字符串表示的字母表。然后“i”表示整数。 A到i。这是一种方式。另一种方法是知道“atoi”的来源,显然是“ASCII 到整数”:stackoverflow.com/a/2909772/1544473
【解决方案2】:

转换简单字符串

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

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

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

这是一个使用上述函数的示例(在 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
}

【讨论】:

  • ParseInt 的第二个参数指定了什么?
  • @kaushik94 单击strconv.ParseInt() 链接,您会立即看到:ParseInt(s string, base int, bitSize int)。所以它是基数:"ParseInt 解释给定基数(2 到 36)中的字符串 s"
  • 请注意,strconv.ParseInt() 的 bitSize 参数不会将字符串转换为您选择的类型,而只是将结果限制为特定的“位数”。另见:stackoverflow.com/questions/55925894/…
  • @viv 是的,没错。如果需要int 类型的值并使用strconv.ParseInt(),则需要手动类型转换(从int64int)。
【解决方案3】:

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

  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

【讨论】:

【解决方案4】:

试试这个

import ("strconv")

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

【讨论】:

    【解决方案5】:

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

    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
    

    【讨论】:

    • 什么?真的吗 ?写“go”的人变得很容易。不要转动你的轮子:)
    • Atoi("-9999") 呢?
    猜你喜欢
    • 1970-01-01
    • 2018-02-04
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    相关资源
    最近更新 更多