Soru Tarihi: Go'da string'ler (string) — temel ve sıklıkla kullanılan bir türdür, veri alışverişi, günlük kaydı, ayrıştırma vb. için aktif bir şekilde kullanılır. Go'nun özelliği, string'lerin değişmez olmasıdır; değiştirilemeyen bir bayt dizisinden oluşurlar ve UTF-8 formatında veri içerebilirler.
Problem: String'lerle ve bayt dilimleriyle ([]byte) çalışırken karışıklık yaratılır, string'i değiştirme, run'lara göre kesme ve çok baytlı karakterlerle (örneğin, Kiril alfabesi, emoji) çalışma girişimlerinde hatalar yapılır.
Çözüm:
String değişmezdir, dolayısıyla doğrudan elemanlarını değiştirmek mümkün değildir — s[0]'ı değiştirme girişimi geçersizdir. String, UTF-8 formatında kodlanır; yani bir karakter (run) bir bayttan daha geniş olabilir. []byte ile çalışma daha ucuzdur, ancak manuel kontrol gerektirir. string <-> []byte dönüşümü her zaman bir kopya oluşturur.
Kod örneği:
s := "merhaba" fmt.Println(len(s)) // 12 bayt (Kiril alfabesi: 2 bayt) fmt.Println(len([]rune(s))) // 6 run, bu kadar harf fmt.Println(string([]byte{228, 189, 160, 229, 165, 189})) // Çin karakterleri
Anahtar özellikler:
1. İndeks aracılığıyla bir string'in ayrı bir karakterini değiştirebilir miyiz (örneğin, s[1] = 'a')?
Cevap: Hayır. String'ler değiştirilemez, derleyici hata verecektir. Yeni bir []rune veya []byte dilimi oluşturup, değiştirip, ardından string'e geri dönüştürmek gerekir.
2. len(str) her zaman string'deki karakter sayısıyla eşleşir mi?
Cevap: len(str) — byte sayısıdır, run sayısı (karakterler) değildir. Kiril alfabesi veya emoji için uzun bir string, sezgisel olarak beklenmedik bir değer verebilir. Karakter sayısı için []rune kullanın:
s := "dünya 😀" fmt.Println(len(s)) // 7 fmt.Println(len([]rune(s))) // 5
3. String bir fonksiyona referansla mı yoksa değerle mi aktarılır?
Cevap: Değerle aktarılır, ancak fiziksel olarak içinde bir bellek işaretçisi ve uzunluk saklanır. Aktarıldıktan sonra iki değişken "aynı" metne işaret eder, otomatik olarak kopya oluşturulmaz. Gerçek bellek kopyası, []byte'a veya string'e dönüştürme sırasında ortaya çıkar.
Bir geliştiricinin Rus karakterler içeren bir string'i vardır, ilk 4 baytı alırlar ve ilk harfi almalarını beklerler, ancak sadece bir karakterin yarısını elde ederler - "bozuk" karakterler oluşur.
Artıları: Hızlı ve kısa bir çözüm elde edildi. Eksileri: Unicode verileri ile yanlış çalışma, "bozuk" string'ler, başka yerlerde böyle string'leri ayrıştırma girişiminde panik.
String'ler karakterlerle çalışmak için []rune'a dönüştürülür, gereken işlemlerden sonra geri string () ile birleştirilir. []byte ile çalışma sadece düşük seviyeli sıralama için yapılır, kodlama dikkate alınarak.
Artıları: Unicode'un doğru işlenmesi, fonksiyonların güvenilirliği. Eksileri: Biraz daha yavaş, daha fazla bellek gerektirir, ancak her türlü string için güvenlidir.