ProgramlamaGo Geliştirici

Go'da (string) ile çalışma özelliklerini bilmek, programlama sırasında beklenmedik hatalardan kaçınmak için nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

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:

  • String değişmezdir, indeksle değiştirilemez.
  • String, UTF-8 formatında kodlanır, her zaman 1 karakter = 1 bayt değildir.
  • string <-> []byte dönüşümü kopya oluşturur.

Yanıltıcı Sorular.

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.

Tipik Hatalar ve Anti-Desenler

  • İndeksleme yoluyla string'i doğrudan değiştirme girişimi.
  • len ile string uzunluğunu karşılaştırmak — Unicode hataları.
  • Sıralama için []byte kullanımı ama kodlamayı unutarak.
  • string ve []byte'ın bellekte farklı nesneler olduğunu unutmamak.

Gerçek Hayat Örneği

Olumsuz Durum

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.

Olumlu Durum

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.