real positive now must logicals language integers golang español go type-conversion

go - positive - time to string php



¿Convertir cadena a tipo entero en Go? (4)

Estoy tratando de convertir una cadena devuelta desde flag.Arg(n) a un int . ¿Cuál es la forma idiomática de hacer esto en Go?


Por ejemplo,

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


Conversión de cadenas simples

La forma más fácil es usar la función strconv.Atoi() .

Tenga en cuenta que hay muchas otras formas. Por ejemplo fmt.Sscan() y strconv.ParseInt() que dan una mayor flexibilidad ya que puede especificar la base y el tamaño del bit por ejemplo. También como se indica en la documentación de strconv.Atoi() :

Atoi es una abreviatura de ParseInt (s, 10, 0).

Aquí hay un ejemplo con las funciones mencionadas (pruébelo en el campo de juego Go ):

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

Salida (si se llama con el argumento "123" ):

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

Análisis de cadenas personalizadas

También hay un útil fmt.Sscanf() que ofrece una mayor flexibilidad ya que con la cadena de formato puede especificar el formato del número (como ancho, base, etc.) junto con caracteres adicionales adicionales en la string entrada.

Esto es ideal para analizar cadenas personalizadas con un número. Por ejemplo, si su entrada se proporciona en forma de "id:00123" donde tiene un prefijo "id:" y el número se fija 5 dígitos, rellenado con ceros si es más corto, esto es muy fácil de analizar de esta manera:

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


Aquí hay tres formas de analizar cadenas en enteros, desde el tiempo de ejecución más rápido hasta el más lento:

  1. strconv.Sscanf(...) más rápido
  2. strconv.Atoi(...) sigue siendo muy rápido
  3. fmt.Sscanf(...) no terriblemente rápido pero más flexible

Aquí hay un punto de referencia que muestra el uso y el tiempo de ejemplo para cada función:

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

Puede ejecutarlo guardando como atoi_test.go y ejecutando go test -bench=. 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


Si controla los datos de entrada, puede usar la versión 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 } }

la opción más rápida (escriba su cheque si es necesario). Resultado:

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