Tekenreeks converteren naar een geheel getal in Go?

Ik probeer een tekenreeks die wordt geretourneerd door flag.Arg(n)te converteren naar een int. Wat is de idiomatische manier om dit in Go te doen?


Antwoord 1, autoriteit 100%

Bijvoorbeeld

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

Antwoord 2, autoriteit 24%

Eenvoudige strings converteren

De gemakkelijkste manier is om de strconv.Atoi()functie.

Houd er rekening mee dat er veel andere manieren zijn. Bijvoorbeeld fmt.Sscan()en strconv.ParseInt()die meer flexibiliteit bieden omdat u de basis en bitgrootte kunt specificeren voor voorbeeld. Ook zoals vermeld in de documentatie van strconv.Atoi():

Atoi is gelijk aan ParseInt(s, 10, 0), geconverteerd naar het type int.

Hier is een voorbeeld waarin de genoemde functies worden gebruikt (probeer het op de 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)
}

Uitvoer (indien aangeroepen met argument "123"):

i=123, type: int
i=123, type: int64
i=123, type: int

Aangepaste tekenreeksen ontleden

Er is ook een handige fmt.Sscanf()wat nog meer flexibiliteit geeft, aangezien u met de opmaakreeks het getalformaat (zoals breedte, grondtal enz.) samen met extra extra tekens in de invoer stringkunt specificeren.

Dit is geweldig voor het ontleden van aangepaste strings met een nummer. Als uw invoer bijvoorbeeld wordt verstrekt in de vorm van "id:00123"waarbij u een voorvoegsel "id:"heeft en het nummer vast 5 cijfers is, opgevuld met nullen indien korter, is dit heel gemakkelijk als volgt te parseren:

s := "id:00123"
var i int
if _, err := fmt.Sscanf(s, "id:%5d", &i); err == nil {
    fmt.Println(i) // Outputs 123
}

Antwoord 3, autoriteit 9%

Hier zijn drie manieren om strings in gehele getallen te ontleden, van de snelste runtime tot de langzaamste:

  1. strconv.ParseInt(...)snelste
  2. strconv.Atoi(...)nog steeds erg snel
  3. fmt.Sscanf(...)niet erg snel maar zeer flexibel

Hier is een benchmark die het gebruik en de voorbeeldtiming voor elke functie laat zien:

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

U kunt het uitvoeren door als atoi_test.gote sparen en te gebruiken 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

Antwoord 4, Autoriteit 2%

Probeer dit

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

Antwoord 5

Als u de invoergegevens bedient, kunt u de MINI-versie

gebruiken

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

de snelste optie (schrijf indien nodig uw cheque). Resultaat:

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

Other episodes