Je dois convertir un int32
en string
dans Golang. Est-il possible de convertir int32
en string
dans Golang sans convertir d'abord int
ou int64
Itoa
a besoin d'une int
. FormatInt
a besoin d'un int64
.
La réponse à une ligne est fmt.Sprint(i)
.
Quoi qu'il en soit, il existe de nombreuses conversions, même à l'intérieur d'une fonction de bibliothèque standard telle que fmt.Sprint(i)
. Vous avez donc quelques options (essayez The Go Playground ):
1- Vous pouvez écrire votre fonction de conversion (Fastest):
func String(n int32) string {
buf := [11]byte{}
pos := len(buf)
i := int64(n)
signed := i < 0
if signed {
i = -i
}
for {
pos--
buf[pos], i = '0'+byte(i%10), i/10
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
2- Vous pouvez utiliser fmt.Sprint(i)
(Slow)
Voir à l'intérieur:
// Sprint formats using the default formats for its operands and returns the resulting string.
// Spaces are added between operands when neither is a string.
func Sprint(a ...interface{}) string {
p := newPrinter()
p.doPrint(a)
s := string(p.buf)
p.free()
return s
}
3- Vous pouvez utiliser strconv.Itoa(int(i))
(Fast)
Voir à l'intérieur:
// Itoa is shorthand for FormatInt(int64(i), 10).
func Itoa(i int) string {
return FormatInt(int64(i), 10)
}
4- Vous pouvez utiliser strconv.FormatInt(int64(i), 10)
(Faster)
Voir à l'intérieur:
// FormatInt returns the string representation of i in the given base,
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
// for digit values >= 10.
func FormatInt(i int64, base int) string {
_, s := formatBits(nil, uint64(i), base, i < 0, false)
return s
}
Comparaison et benchmark (avec 50000000 itérations):
s = String(i) takes: 5.5923198s
s = String2(i) takes: 5.5923199s
s = strconv.FormatInt(int64(i), 10) takes: 5.9133382s
s = strconv.Itoa(int(i)) takes: 5.9763418s
s = fmt.Sprint(i) takes: 13.5697761s
Code:
package main
import (
"fmt"
//"strconv"
"time"
)
func main() {
var s string
i := int32(-2147483648)
t := time.Now()
for j := 0; j < 50000000; j++ {
s = String(i) //5.5923198s
//s = String2(i) //5.5923199s
//s = strconv.FormatInt(int64(i), 10) // 5.9133382s
//s = strconv.Itoa(int(i)) //5.9763418s
//s = fmt.Sprint(i) // 13.5697761s
}
fmt.Println(time.Since(t))
fmt.Println(s)
}
func String(n int32) string {
buf := [11]byte{}
pos := len(buf)
i := int64(n)
signed := i < 0
if signed {
i = -i
}
for {
pos--
buf[pos], i = '0'+byte(i%10), i/10
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
func String2(n int32) string {
buf := [11]byte{}
pos := len(buf)
i, q := int64(n), int64(0)
signed := i < 0
if signed {
i = -i
}
for {
pos--
q = i / 10
buf[pos], i = '0'+byte(i-10*q), q
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
Utilisez un conversion et strconv.FormatInt pour formater les valeurs int32 en tant que chaîne. La conversion a un coût nul sur la plupart des plateformes.
s := strconv.FormatInt(int64(n), 10)
Si vous avez plusieurs appels comme celui-ci, envisagez d'écrire une fonction d'assistance similaire à strconv.Itoa :
func formatInt32(n int32) string {
return strconv.FormatInt(int64(n), 10)
}
Tout le code de formatage entier de bas niveau dans la bibliothèque standard fonctionne avec les valeurs int64
. Toute réponse à cette question utilisant le code de formatage dans la bibliothèque standard (paquet fmt inclus) nécessite un conversion to int64
quelque part. Le seul moyen d'éviter la conversion est d'écrire la fonction de formatage à partir de zéro, mais cela ne sert à rien de le faire.