[string] Go에서 문자열을 정수 유형으로 변환 하시겠습니까?

에서 반환 된 문자열을로 변환하려고 flag.Arg(n)합니다 int. Go에서 이것을 수행하는 관용적 방법은 무엇입니까?



답변

예를 들어

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


답변

간단한 문자열 변환

가장 쉬운 방법은 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)
}

출력 (argument와 함께 호출 된 경우 "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


답변

이 시도

import ("strconv")

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


답변

입력 데이터를 제어하면 미니 버전을 사용할 수 있습니다

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


답변