Go tipleri asla örtük olarak dönüştürmez. Uyumlu tipler arasında T(v) ile, sayılar ile metin arasında ise strconv paketiyle dönüşüm yaparsınız. En çok aranan iki dönüşüm:
strconv.Itoa ("integer to ASCII") bir int'i ondalık metin olarak biçimlendirir. strconv.Atoi ("ASCII to integer") metni bir int'e ayrıştırır ve metin geçerli bir sayı değilse hata döndürür. Bu hatayı her zaman kontrol edin.
T(v) Dönüşümü
Go'nun dönüşüm söz dizimi, hedef tipin adını taşıyan bir fonksiyon çağrısına benzer. Üç durumda çalışır:
- sayısal tipler arasında (
int,int64,float64,uint8, ...), stringile[]byteya da[]runearasında,- aynı temel tipi paylaşan tipler arasında (
Celsiusvefloat64).
Sonuçları dikkatle okuyun:
int(3.9)sonucu3,int(-3.9)sonucu-3'tür. Dönüşüm sıfıra doğru keser; yuvarlamaz. Davranışı seçmek için öncemath.Round,math.Floorya damath.Ceilkullanın.math.Roundyarımları sıfırdan uzağa yuvarlar, yani-3.5,-4olur.uint8(300)sonucu44'tür, çünkü yalnızca alt 8 bit kalır (300 eksi 256);int8(200)de aynı nedenle-56'dır. Hata yok, panic yok.Celsiusvefloat64aynı temel tipi paylaşır, bu yüzden serbestçe dönüşürler, ama yalnızca açıkça.
Değerler bilerek değişkenlerde tutuluyor. Sabitlerle aynı dönüşümler derlenmez.
Sabitler Kontrol Edilir, Değişkenler Edilmez
Sığmayan bir sabiti dönüştürmek derleme hatasıdır. Aynı değere sahip bir değişkeni dönüştürmek ise sessizce başa sarar:
fmt.Println(uint8(300)) // compile error
x := 300
fmt.Println(uint8(x)) // 44
./main.go:6:20: constant 300 overflows uint8
Tam sayı olmayan bir sabiti tam sayı tipine dönüştürmek de reddedilir; aynı değer bir değişkendeyse kesilir:
./main.go:7:18: cannot convert -3.9 (untyped float constant) to type int
Float değeri hedef tam sayı tipinin aralığı dışındaysa (örneğin int64(1e20)) sonuç uygulamaya bağlıdır: örneğin amd64 ve arm64 farklı cevaplar verir. Güvenilmeyen değerleri dönüştürmeden önce aralığı kontrol edin.
Sayıları String'e Dönüştürmek
| Kaynak | Fonksiyon | Örnek | Sonuç |
|---|---|---|---|
int | strconv.Itoa(n) | strconv.Itoa(-7) | "-7" |
int64 | strconv.FormatInt(n, base) | strconv.FormatInt(255, 16) | "ff" |
uint64 | strconv.FormatUint(n, base) | strconv.FormatUint(5, 2) | "101" |
float64 | strconv.FormatFloat(f, fmt, prec, 64) | strconv.FormatFloat(3.14159, 'f', 2, 64) | "3.14" |
bool | strconv.FormatBool(b) | strconv.FormatBool(true) | "true" |
| herhangi bir şey | fmt.Sprint(v) | fmt.Sprint(3.5) | "3.5" |
| herhangi bir şey, biçimli | fmt.Sprintf(format, v) | fmt.Sprintf("%05d", 42) | "00042" |
FormatFloat bir format baytı (sabit için 'f', üslü gösterim için 'e', hangisi kısaysa onun için 'g'), bir hassasiyet (-1, "tam olarak geri dönüşebilen en az basamak" demektir) ve orijinal float'ın bit boyutunu (64 ya da 32) alır.
strconv, değeri bir interface'e kutulayıp fmt'nin genel biçimlendirme yolundan geçen fmt.Sprint'ten daha hızlıdır. Sık çalışan bir döngüde bu fark görünür; ara sıra yapılan dönüşümler için hangisi daha okunaklıysa onu seçin.
String'leri Sayılara Dönüştürmek
| Hedef | Fonksiyon | Döndürdüğü |
|---|---|---|
int | strconv.Atoi(s) | int, error |
| herhangi bir işaretli tam sayı | strconv.ParseInt(s, base, bitSize) | int64, error |
| herhangi bir işaretsiz tam sayı | strconv.ParseUint(s, base, bitSize) | uint64, error |
| float | strconv.ParseFloat(s, bitSize) | float64, error |
| bool | strconv.ParseBool(s) | bool, error |
ParseInt her zaman bir int64 döndürür. bitSize argümanı (0, 8, 16, 32, 64) kabul ettiği aralığı belirler, bu yüzden sonucu küçük bir tipe dönüştürdüğünüzde sığması garantidir. base 0 "önekten çıkar" demektir, bu yüzden 0x1f, 0o17, 0b101 ve 1_000'in hepsi ayrıştırılır.
Çıktının gösterdikleri:
" 42"başarısız olur.Atoiisteğe bağlı bir işaret ve rakamlar kabul eder, başka hiçbir şey değil.bufio'dan gelen girdi genellikle\nile biter, bu yüzden kırpın."4.2",Atoiiçin geçersizdir. Ondalıklı sayılar içinParseFloatkullanın.- Aralık dışı bir hatada
ParseInt, hatayla birlikte sığan en büyük değeri döndürür (int8için127). Hata nil değilse değeri kullanmayın. - Hatalar,
strconv.ErrSyntaxya dastrconv.ErrRange'i sarmalayan*strconv.NumErrordeğerleridir, bu yüzdenerrors.Isonları ayırt edebilir.
ParseBool; 1, t, T, TRUE, true, True ve bunlara karşılık gelen false biçimlerini kabul eder. "yes" ve "on" hatadır.
string(65) Tuzağı
Bir tam sayıyı string'e dönüştürmek rakamlar üretmez. O Unicode kod noktasına sahip karakteri üretir:
n := 65
s := string(n) // "A", not "65"
Derleyici bunu kabul eder, ama go vet raporlar:
./main.go:10:7: conversion from int to string yields a string of one rune, not a string of digits
Gerçekten karakteri istiyorsanız bunu bir rune ile belirtin: string(rune(n)). Sayıyı metin olarak istiyorsanız strconv.Itoa(n) kullanın. Bir rune ya da byte'ı string'e dönüştürmek ise sorunsuz ve yaygındır:
String'ler, Byte'lar ve Rune'lar
string, []byte ve []rune birbirine T(v) ile dönüşür. String'ler değiştirilemez, slice'lar değiştirilebilir olduğu için her dönüşüm veriyi kopyalar:
Karaktere göre indekslemeniz ya da değişiklik yapmanız gerekiyorsa []rune'a, G/Ç, hash'leme ve bayt seviyesinde düzenlemeler için []byte'a dönüştürün. Runes and bytes sayfası UTF-8'i ayrıntılı anlatıyor.
Dönüşüm ve Type Assertion
Dönüşüm bir değeri bir somut tipten diğerine çevirir. Bir interface'ten (any, error, io.Reader) somut değeri çıkarmak ise farklı bir işlemdir, type assertion:
var v any = 42
n := v.(int) // type assertion: v holds an int, give it to me
f := float64(n) // conversion: int to float64
// f := float64(v) // compile error: cannot convert v (variable of interface type any)
// // to type float64: need type assertion
Önce assertion, sonra dönüşüm. Virgül-ok biçimi n, ok := v.(int), tip yanlış olduğunda panic'i önler.
Hızlı Başvuru
| Görev | Kod |
|---|---|
| int'ten string'e | strconv.Itoa(n) |
| int64'ten string'e | strconv.FormatInt(n, 10) |
| string'den int'e | n, err := strconv.Atoi(s) |
| string'den int64'e | n, err := strconv.ParseInt(s, 10, 64) |
| string'den float64'e | f, err := strconv.ParseFloat(s, 64) |
| float64'ten string'e | strconv.FormatFloat(f, 'f', -1, 64) |
| float64'ten int'e | int(f) (keser) ya da int(math.Round(f)) |
| int'ten float64'e | float64(n) |
| string'den []byte'a | []byte(s) |
| []byte'tan string'e | string(b) |
| rune'dan string'e | string(r) |
| bool'dan string'e | strconv.FormatBool(b) |
| herhangi bir değerden string'e | fmt.Sprint(v) |
Sıkça Sorulan Sorular
Go'da bir int nasıl string'e dönüştürülür?
strconv.Itoa(n) kullanın: strconv.Itoa(42), "42" döndürür. Bir int64 için strconv.FormatInt(n, 10) kullanın. fmt.Sprint(n) de her tip için çalışır ama daha yavaştır. string(n) yazmayın: bu n'i bir Unicode kod noktası olarak ele alır, yani string(65) sonucu "A" olur.
Go'da bir string nasıl int'e dönüştürülür?
Sayıyı ve bir hatayı döndüren strconv.Atoi kullanın:
n, err := strconv.Atoi("42")
if err != nil {
// not a valid integer
}
Belirli bir boyut ya da taban için bir int64 döndüren strconv.ParseInt(s, 10, 64) kullanın. Atoi boşlukları kırpmaz, bu yüzden " 42" bir hatadır; önce strings.TrimSpace çağırın.
Go'da cast nasıl yapılır?
Go buna dönüşüm (conversion) der ve söz dizimi T(v) şeklindedir: float64(n), int(f), []byte(s). Sayısal tipler arasında, string'ler ile byte ya da rune slice'ları arasında ve aynı temel tipe sahip tipler arasında çalışır. Metni ayrıştırmaz: "42"'yi 42'ye çevirmek strconv gerektirir. Bir interface'ten somut bir tipi çıkarmak dönüşüm değil, bir type assertion'dır: v.(T).
Go'da bir float nasıl int'e dönüştürülür?
int(f) sıfıra doğru keser: int(3.9) sonucu 3, int(-3.9) sonucu -3'tür. Yuvarlamak için int(math.Round(f)) kullanın. Float, tam sayı tipinin aralığı dışındaysa sonuç uygulamaya bağlıdır, bu yüzden değer girdiden geliyorsa önce aralığı kontrol edin.
Go'da string(65) neden "A" döndürür?
Bir tam sayıyı string'e dönüştürmek onu bir Unicode kod noktası olarak yorumlar ve 65, A'nın kod noktasıdır. go vet bunu işaretler: conversion from int to string yields a string of one rune, not a string of digits. "65" elde etmek için strconv.Itoa(65) kullanın.