Ich versuche, eine zurückgegebene Zeichenfolge flag.Arg(n)
in eine zu konvertieren int
. Was ist der idiomatische Weg, dies in Go zu tun?
Ich versuche, eine zurückgegebene Zeichenfolge flag.Arg(n)
in eine zu konvertieren int
. Was ist der idiomatische Weg, dies in Go zu tun?
Antworten:
Beispielsweise,
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)
Am einfachsten ist es, die strconv.Atoi()
Funktion zu verwenden.
Beachten Sie, dass es viele andere Möglichkeiten gibt. Zum Beispiel fmt.Sscan()
und strconv.ParseInt()
die eine größere Flexibilität bieten, da Sie beispielsweise die Basis und die Bitgröße angeben können. Auch wie in der Dokumentation von strconv.Atoi()
:
Atoi entspricht ParseInt (s, 10, 0) und wird in den Typ int konvertiert.
Hier ist ein Beispiel mit den genannten Funktionen (probieren Sie es auf dem Go Playground aus ):
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)
}
Ausgabe (wenn mit Argument aufgerufen "123"
):
i=123, type: int
i=123, type: int64
i=123, type: int
Es gibt auch eine praktische Funktion, fmt.Sscanf()
die noch mehr Flexibilität bietet, da Sie mit der Formatzeichenfolge das Zahlenformat (wie Breite, Basis usw.) zusammen mit zusätzlichen zusätzlichen Zeichen in der Eingabe angeben können string
.
Dies ist ideal zum Parsen von benutzerdefinierten Zeichenfolgen, die eine Zahl enthalten. Wenn Ihre Eingabe beispielsweise in einer Form erfolgt, in der "id:00123"
Sie ein Präfix haben "id:"
und die Zahl auf 5 Stellen festgelegt ist, die mit Nullen aufgefüllt sind, wenn sie kürzer sind, kann dies sehr einfach wie folgt analysiert werden:
s := "id:00123"
var i int
if _, err := fmt.Sscanf(s, "id:%5d", &i); err == nil {
fmt.Println(i) // Outputs 123
}
ParseInt
spezifizieren?
strconv.ParseInt()
Link und Sie sehen sofort : ParseInt(s string, base int, bitSize int)
. Es ist also die Basis: "ParseInt interpretiert einen String s in der angegebenen Basis (2 bis 36)"
int
erforderlich ist und strconv.ParseInt()
verwendet wird, ist eine manuelle Typkonvertierung erforderlich (von int64
nach int
).
Hier sind drei Möglichkeiten, um Zeichenfolgen in Ganzzahlen zu analysieren, von der schnellsten bis zur langsamsten Laufzeit:
strconv.ParseInt(...)
am schnellstenstrconv.Atoi(...)
immer noch sehr schnellfmt.Sscanf(...)
nicht besonders schnell, aber am flexibelstenHier ist ein Benchmark, der die Verwendung und das Beispiel-Timing für jede Funktion zeigt:
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)
}
}
}
Sie können es ausführen, indem Sie es speichern atoi_test.go
und ausführen 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
Versuche dies
import ("strconv")
value : = "123"
number,err := strconv.ParseUint(value, 10, 32)
Wenn Sie die Eingabedaten steuern, können Sie die Mini-Version verwenden
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
}
}
die schnellste Option (schreiben Sie Ihren Scheck, falls erforderlich). Ergebnis:
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
func main() { ... }
Nimmt keine Argumente und gibt keinen Wert zurück. Verwenden Sie dieos
Paket -Exit
Funktion zBos.Exit(2).