ProgramlamaBackend Geliştirici

Go'da Stringer ve Error yerleşik yöntemleri nedir, ne için kullanılır ve kendi yapılandırmalarınızı nasıl doğru bir şekilde uygulamalısınız?

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

Cevap.

Go'da fmt.Stringer ve error arayüzleri, bir yapı değerinin nasıl dizeye çevrileceğini ve hatanın nasıl uygulandığını yönetmek için kullanılır. Bu arayüzler, loglama, çıktı verme ve hata ile çalışma konusunda evrensel yöntemler sağlayarak kodu daha esnek ve anlaşılır hale getirir.

Konu geçmişi:

Go'nun ilk sürümlerinden itibaren Stringer arayüzü, yapının güzel bir şekilde kontrol edilen çıktısı için temel bir unsur haline geldi. Error arayüzü, kodun her seviyesinde hata işleme için temel bir yapı olarak ortaya çıktı.

Problem:

Programcılar genellikle bu yöntemleri uygulamadıkları veya standart dışı uyguladıkları için bilgi vermeyen çıktılar veya beklenmedik hata mesajları alırlar. Ayrıca, yanlış uygulama, döngüsel çıktılara, paniklere ve okunması zor hatalara yol açabilir.

Çözüm:

  • Yapılarınızın fmt.Print* içindeki temsillerini yönetmek istiyorsanız String() string metodunu uygulayın.
  • Kullanıcı tanımlı hata türleri için Error() string metodunu uygulayın.

Kod örneği:

package main import "fmt" type User struct { Name string ID int } func (u User) String() string { return fmt.Sprintf("User<%d:%s>", u.ID, u.Name) } type MyError struct { Msg string } func (e MyError) Error() string { return "MyError: " + e.Msg } func main() { u := User{Name: "Bob", ID: 10} fmt.Println(u) // String() çağrılır. err := MyError{Msg:"fail"} fmt.Println(err) // Error() çağrılır. }

Anahtar özellikler:

  • String() ve Error() yöntemleri, çıktı alırken veya log kaydı yaparken atomik olarak çağrılır.
  • Hatalı String() uygulaması, içinde tekrar fmt.Sprintf çağırdığınızda sonsuz döngüye neden olabilir.
  • Error() ile hata standartlaştırması, hata işlemeden ve izleme süreçlerini basitleştirir.

Kandırmaca soruları.

String() veya Error() yöntemlerini değer yöntemleri olarak uygulamak zorunlu mu yoksa işaretçiler de kullanılabilir mi?

Her iki seçenek de geçerlidir, ancak işaretçi alıcı ve değer alıcı uygulanması, yöntemin hangi nesne türlerinde çalışacağını etkiler. Genellikle değişken yapılandırmalar için işaretçi alıcısı kullanılır.

func (u *User) String() string {...}

String() veya Error() içinde fmt.Sprintf kullanabilir miyiz?

Evet, ancak sonsuz döngüye neden olmamak için dikkatli olunmalıdır (örneğin, String() içinde aynı türden bir yapının çıktısını almak gibi). İçinde tekrar String() çağırmayacaksa String() içinde fmt.Print kullanmaktan kaçınılması önerilir.

func (u User) String() string { return fmt.Sprintf("%v", u.Name) } // güvenli

Error() metodu boş bir dize dönerse ne olur?

Boş dize içeren hatalar geçerli error değerleri olarak değerlendirilir, ancak loglama anlamını kaybeder. Error arayüzü boş bir dize ile ilgili bir davranış tanımlamaz, ancak daima bilgi verici bir mesaj vermek yaygın bir uygulamadır.

Yaygın hatalar ve anti-pat alınan yollar

  • String() içinde döngüsel çağrı fmt.Sprintf
  • Error() içinde örtük bilgi kaybı
  • Yöntem adları dizgisel, ancak dışa aktarımları yok (sözdizim hatası)

Gerçek hayattan örnekler

Negatif vaka

Bir geliştirici String() uygulamadan %+v ile bir yapıyı çıktılar, sonuçta loglarda alanların çöp dökümlerini alır.

Artıları:

  • Hızlı, şık bir çıktı için maliyet gerektirmiyor.

Eksileri:

  • Loglar okunamaz, bakım zor, kullanıcı çıktısında kötü görünüm

Pozitif vaka

Tim lideri, ekibi tüm kamu yapıları için String() ve Error() uygulamaya zorlar. Sonuç olarak, iş mantığı hataları merkezi olarak işler ve yönetim paneli ile hata ayıklama logları okunabilir hale gelir.

Artıları:

  • Şeffaf hata izleme
  • Açık, kontrol edilebilir yapı çıktısı

Eksileri:

  • Yapıda değişiklik yapıldığında manuel olarak desteklenmelidir.