error Arayüzü
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 52 / 107.
Go'da hatalar, error adı verilen yerleşik bir arayüz aracılığıyla yönetilir. Bu arayüz oldukça basittir; yalnızca tek bir metot gerektirir:
type error interface {
Error() string
}Bir string döndüren Error() metodunu uygulayan herhangi bir tür, error arayüzünü otomatik olarak karşılar. Bu, Go'nun iş başındaki arayüz sistemidir; açık bir bildirime gerek yoktur.
Hata oluşturmanın en yaygın yolu errors paketini kullanmaktır:
import "errors"
func Divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}Go fonksiyonları genellikle son dönüş değeri olarak bir hata döndürür. Hiçbir hata oluşmadığında, nil döndürürsünüz. Çağıran taraf, devam etmeden önce hatanın nil olup olmadığını kontrol eder:
result, err := Divide(10, 0)
if err != nil {
fmt.Println("Error:", err.Error())
return
}
fmt.Println("Result:", result)Biçimlendirilmiş hata mesajları oluşturmak için fmt.Errorf işlevini de kullanabilirsiniz:
func GetUser(id int) (string, error) {
if id <= 0 {
return "", fmt.Errorf("invalid user id: %d", id)
}
return "Alice", nil
}Hata fırlatmak yerine hata döndürme kalıbı Go için temeldir. Bu, hata yönetimini açık hale getirir ve işler ters gittiğinde ne olacağını düşünmeye zorlar; bu da sağlam, nesne yönelimli kod yazmanın temel bir yönüdür.
Görev
KolayGo'nin hata işleme desenini gösteren bir banka hesabı sistemi kuralım. İşlemleri doğrulayan ve bir şeyler ters gittiğinde anlamlı hatalar döndüren basit bir hesap oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
account.go: Dışa aktarılan (exported) birOwneralanına (string) ve dışa aktarılmayan (unexported) birbalancealanına (float64) sahip birBankAccountyapısı (struct) oluşturun. Şunları uygulayın:NewBankAccount(owner string, initialDeposit float64) (*BankAccount, error)- ilk depozito sıfır veya negatifse"initial deposit must be positive"mesajıyla bir hata döndüren bir yapıcı (constructor). Aksi takdirde, hesabı oluşturun ve döndürün.Deposit(amount float64) error- bakiyeye para ekler. Miktar sıfır veya negatifse"deposit amount must be positive"mesajıyla bir hata döndürün.Withdraw(amount float64) error- bakiyeden para çeker. Miktar sıfır veya negatifse"withdrawal amount must be positive"mesajıyla veya bakiye çekilecek miktardan azsa"insufficient funds"mesajıyla bir hata döndürün.Balance() float64- mevcut bakiyeyi döndürür
main.go: Girdiden hesap ayrıntılarını ve işlem miktarlarını okuyun. Bir hesap oluşturmaya ve işlemleri gerçekleştirmeye çalışın. Her işlemden sonra ya başarı mesajını ya da hata mesajını yazdırın.
Aşağıdaki girdiler sağlanacaktır:
- Satır 1: Sahip adı (Owner name)
- Satır 2: İlk depozito miktarı
- Satır 3: Yatırılacak miktar
- Satır 4: Çekilecek miktar
Her işlem için sonucu yazdırın:
- Hesap oluşturulduktan sonra:
Account created for [Owner] with balance: $[balance]veyaError: [error message] - Para yatırdıktan sonra:
Deposited successfully. New balance: $[balance]veyaError: [error message] - Para çektikten sonra:
Withdrew successfully. New balance: $[balance]veyaError: [error message]
Tüm bakiye değerlerini iki ondalık basamakla biçimlendirin. Hesap oluşturma başarısız olursa, kalan işlemleri atlayın.
Örneğin, Alice, 100, 50 ve 200 verildiğinde çıktınız şöyle olmalıdır:
Account created for Alice with balance: $100.00
Deposited successfully. New balance: $150.00
Error: insufficient fundsVe Bob, -50, 25 ve 10 verildiğinde çıktınız şöyle olmalıdır:
Error: initial deposit must be positiveKopya kağıdı
Go, hataları tek bir metot gerektiren yerleşik error arayüzü aracılığıyla yönetir:
type error interface {
Error() string
}errors paketini kullanarak hatalar oluşturun:
import "errors"
func Divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}Fonksiyonlar hataları son dönüş değeri olarak döndürür. Herhangi bir hata oluşmadığında nil döndürün:
result, err := Divide(10, 0)
if err != nil {
fmt.Println("Error:", err.Error())
return
}
fmt.Println("Result:", result)Formatlanmış hata mesajları için fmt.Errorf kullanın:
func GetUser(id int) (string, error) {
if id <= 0 {
return "", fmt.Errorf("invalid user id: %d", id)
}
return "Alice", nil
}Kendin dene
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Sahip adını oku
ownerName, _ := reader.ReadString('\n')
ownerName = strings.TrimSpace(ownerName)
// Başlangıç depozitosunu oku
initialDepositStr, _ := reader.ReadString('\n')
initialDeposit, _ := strconv.ParseFloat(strings.TrimSpace(initialDepositStr), 64)
// Yatırılacak tutarı oku
depositStr, _ := reader.ReadString('\n')
depositAmount, _ := strconv.ParseFloat(strings.TrimSpace(depositStr), 64)
// Çekilecek tutarı oku
withdrawStr, _ := reader.ReadString('\n')
withdrawAmount, _ := strconv.ParseFloat(strings.TrimSpace(withdrawStr), 64)
// TODO: NewBankAccount kullanarak yeni bir banka hesabı oluşturun
// Bir hata oluşursa, "Error: [error message]" yazdırın ve return ile çıkın
// Başarılı olursa, "Account created for [Owner] with balance: $[balance]" yazdırın
// TODO: Yatırılacak tutarı yatırmayı deneyin
// Bir hata oluşursa, "Error: [error message]" yazdırın
// Başarılı olursa, "Deposited successfully. New balance: $[balance]" yazdırın
// TODO: Çekilecek tutarı çekmeyi deneyin
// Bir hata oluşursa, "Error: [error message]" yazdırın
// Başarılı olursa, "Withdrew successfully. New balance: $[balance]" yazdırın
// Bakiye değerlerini fmt.Printf("%.2f", balance) kullanarak iki ondalık basamakla formatlamayı unutmayın
_ = ownerName
_ = initialDeposit
_ = depositAmount
_ = withdrawAmount
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker Pool