Saya mencoba mengonversi string yang dikembalikan dari flag.Arg(n)
ke int
. Apa cara idiomatis untuk melakukan ini di Go?
Saya mencoba mengonversi string yang dikembalikan dari flag.Arg(n)
ke int
. Apa cara idiomatis untuk melakukan ini di Go?
Jawaban:
Sebagai contoh,
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)
Cara termudah adalah menggunakan strconv.Atoi()
fungsinya.
Perhatikan bahwa ada banyak cara lain. Misalnya fmt.Sscan()
dan strconv.ParseInt()
yang memberikan fleksibilitas lebih besar karena Anda dapat menentukan basis dan bitsize misalnya. Juga seperti yang tercantum dalam dokumentasi strconv.Atoi()
:
Atoi setara dengan ParseInt (s, 10, 0), dikonversi menjadi tipe int.
Berikut ini contoh menggunakan fungsi yang disebutkan (coba di 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)
}
Output (jika dipanggil dengan argumen "123"
):
i=123, type: int
i=123, type: int64
i=123, type: int
Ada juga yang berguna fmt.Sscanf()
yang memberikan fleksibilitas lebih besar karena dengan string format Anda dapat menentukan format angka (seperti lebar, basis dll) bersama dengan karakter tambahan tambahan dalam input string
.
Ini bagus untuk parsing string kustom yang memegang nomor. Misalnya, jika input Anda diberikan dalam bentuk di "id:00123"
mana Anda memiliki awalan "id:"
dan jumlahnya ditetapkan 5 digit, diisi dengan nol jika lebih pendek, ini sangat mudah diurai seperti ini:
s := "id:00123"
var i int
if _, err := fmt.Sscanf(s, "id:%5d", &i); err == nil {
fmt.Println(i) // Outputs 123
}
ParseInt
ditentukan argumen kedua ?
strconv.ParseInt()
link di dan Anda akan melihat langsung: ParseInt(s string, base int, bitSize int)
. Jadi itulah dasarnya: "ParseInt menginterpretasikan sebuah string dalam basis yang diberikan (2 hingga 36)"
int
diperlukan dan strconv.ParseInt()
digunakan, konversi tipe manual diperlukan (dari int64
menjadi int
).
Berikut adalah tiga cara untuk mengurai string menjadi bilangan bulat, dari runtime tercepat ke yang paling lambat:
strconv.ParseInt(...)
tercepatstrconv.Atoi(...)
masih sangat cepatfmt.Sscanf(...)
tidak terlalu cepat tetapi paling fleksibelBerikut ini adalah tolok ukur yang menunjukkan waktu penggunaan dan contoh untuk setiap fungsi:
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)
}
}
}
Anda dapat menjalankannya dengan menyimpan sebagai atoi_test.go
dan menjalankan 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
Coba ini
import ("strconv")
value : = "123"
number,err := strconv.ParseUint(value, 10, 32)
Jika Anda mengontrol data input, Anda dapat menggunakan versi mini
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
}
}
opsi tercepat (tulis cek Anda jika perlu). Hasil:
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() { ... }
tidak mengambil argumen dan tidak mengembalikan nilai. Gunakan fungsios
paketExit
mis.os.Exit(2).