에서 반환 된 문자열을로 변환하려고 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
}
답변
다음은 가장 빠른 런타임에서 가장 느린 문자열까지 문자열을 정수로 구문 분석하는 세 가지 방법입니다.
strconv.ParseInt(...)
가장 빠른strconv.Atoi(...)
여전히 매우 빠르다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