Error Sentinel
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 55 dari 107.
sentinel error adalah variabel error tingkat package yang telah ditentukan sebelumnya dan mewakili kondisi error tertentu. Berbeda dengan membuat error baru setiap kali menggunakan errors.New, sentinel error dideklarasikan sekali dan digunakan kembali di seluruh kodemu.
Kamu mendefinisikan error sentinel sebagai variabel tingkat package, biasanya dengan nama yang diawali Err:
package user
import "errors"
var (
ErrNotFound = errors.New("user not found")
ErrInvalidEmail = errors.New("invalid email address")
ErrDuplicate = errors.New("user already exists")
)Fungsi mengembalikan error yang telah ditentukan ini ketika kondisi tertentu terjadi:
func FindUser(id int) (*User, error) {
user, exists := users[id]
if !exists {
return nil, ErrNotFound
}
return user, nil
}Keunggulan error sentinel adalah pemanggil dapat memeriksa kondisi error tertentu dengan membandingkan nilai error secara langsung:
user, err := FindUser(42)
if err == ErrNotFound {
fmt.Println("Creating new user...")
} else if err != nil {
fmt.Println("Unexpected error:", err)
}Standard library Go banyak menggunakan error sentinel. Misalnya, io.EOF menandakan akhir input, dan sql.ErrNoRows menunjukkan hasil query yang kosong. Pola ini menciptakan kontrak yang jelas antara package dan penggunanya tentang error yang dapat diharapkan.
Namun, pemeriksaan kesamaan sederhana gagal saat error dibungkus. Di pelajaran berikutnya, kamu akan belajar bagaimana errors.Is() mengatasi masalah ini dengan memeriksa seluruh rantai error.
Tantangan
MudahMari buat sistem manajemen inventaris yang menggunakan error sentinel untuk menyampaikan kondisi kegagalan tertentu. Kamu akan mendefinisikan variabel error di tingkat package yang dapat diperiksa oleh pemanggil untuk menangani berbagai skenario dengan tepat.
Kamu akan mengatur kodemu dalam dua file:
inventory.go: Buat sistem inventaris dengan error sentinel yang telah ditentukan untuk kasus kegagalan umum.Definisikan tiga error sentinel di tingkat package:
ErrItemNotFounddengan pesan"item not found in inventory"ErrOutOfStockdengan pesan"item is out of stock"ErrInsufficientQuantitydengan pesan"insufficient quantity available"
Buat struct
Inventoryyang menyimpan map berisi nama item dan jumlahnya. Implementasikan method berikut:NewInventory() *Inventory- membuat inventaris kosongAddItem(name string, quantity int)- menambahkan atau memperbarui jumlah itemGetQuantity(name string) (int, error)- mengembalikan jumlah suatu item, atauErrItemNotFoundjika item tersebut tidak adaPurchase(name string, quantity int) error- mencoba membeli item. KembalikanErrItemNotFoundjika item tidak ada,ErrOutOfStockjika jumlah saat ini adalah nol, atauErrInsufficientQuantityjika jumlah yang diminta melebihi stok yang tersedia. Jika berhasil, kurangi inventaris dan kembalikannil.
main.go: Baca operasi inventaris dari input dan tunjukkan cara pemanggil dapat memeriksa error sentinel tertentu menggunakan perbandingan kesamaan langsung.Baca nama item dan jumlah yang akan dibeli dari input. Buat inventaris, tambahkan item
"laptop"dengan jumlah5, lalu coba lakukan pembelian. Berdasarkan error yang dikembalikan, cetak pesan khusus yang menunjukkan bahwa kamu berhasil mengidentifikasi error sentinel yang terjadi.
Input berikut akan diberikan:
- Baris 1: Nama item yang akan dibeli
- Baris 2: Jumlah yang akan dibeli
Tangani hasilnya dengan memeriksa error tertentu yang dikembalikan:
- Jika
err == ErrItemNotFound: cetakError: Item '[name]' does not exist in our inventory - Jika
err == ErrOutOfStock: cetakError: Item '[name]' is currently out of stock - Jika
err == ErrInsufficientQuantity: cetakError: Cannot purchase [quantity] units of '[name]' - not enough in stock - Jika berhasil: cetak
Successfully purchased [quantity] units of '[name]'
Contohnya, jika diberikan laptop dan 3, output-mu seharusnya:
Successfully purchased 3 units of 'laptop'Jika diberikan phone dan 2, output-mu seharusnya:
Error: Item 'phone' does not exist in our inventoryJika diberikan laptop dan 10, output-mu seharusnya:
Error: Cannot purchase 10 units of 'laptop' - not enough in stockCoba sendiri
package main
import (
"fmt"
)
func main() {
// Baca input
var itemName string
var quantity int
fmt.Scanln(&itemName)
fmt.Scanln(&quantity)
// Buat inventaris dan tambahkan "laptop" dengan jumlah 5
inv := NewInventory()
inv.AddItem("laptop", 5)
// TODO: Coba beli item tersebut
// Panggil inv.Purchase(itemName, quantity)
// TODO: Periksa error sentinel spesifik yang dikembalikan dengan perbandingan kesamaan langsung
// Gunakan pernyataan if/else if untuk memeriksa:
// - err == ErrItemNotFound
// - err == ErrOutOfStock
// - err == ErrInsufficientQuantity
// - err == nil (berhasil)
// TODO: Cetak pesan yang sesuai berdasarkan error
// Jika ErrItemNotFound: fmt.Printf("Error: Item '%s' does not exist in our inventory\n", itemName)
// Jika ErrOutOfStock: fmt.Printf("Error: Item '%s' is currently out of stock\n", itemName)
// Jika ErrInsufficientQuantity: fmt.Printf("Error: Cannot purchase %d units of '%s' - not enough in stock\n", quantity, itemName)
// Jika berhasil: fmt.Printf("Successfully purchased %d units of '%s'\n", quantity, itemName)
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP di Go
File EksternalWorkspace Go dan modulePaket dan ImporNama yang Diekspor dan Tidak DieksporPengantar OOP di Gostruct sebagai classMendefinisikan method pada structPointer receiver vs value receiverInisialisasi structFungsi KonstruktorUlasan: Kalkulator Sederhana4Interface
Pengenalan InterfaceImplementasi ImplisitInterface sebagai KontrakInterface Kosong (any)Type AssertionType SwitchKomposisi InterfaceInterface Stringer & ErrorUlasan: Kalkulator Bentuk7Enkapsulasi
Field yang Diekspor vs Tidak DieksporEnkapsulasi Tingkat PackageMethod Getter dan SetterPenyembunyian Informasi di GoRingkasan: Data Siswa10Generics (Go 1.18+)
Pengantar GenericsParameter TipeBatasan TipeStruct GenerikCara Alternatif untuk Method GenerikRingkasan Koleksi Generik2Mendalami Tipe dan Struct
Tipe Dasar dan KompositDefinisi Tipe KustomTag StructStruct AnonimStruct BersarangNilai Nol dan Nilai BawaanRangkuman: Buku Kontak5Komposisi daripada Pewarisan
Mengapa Go Tidak Memiliki PewarisanDasar Penyematan StructPromosi methodMenyematkan Beberapa StructPenyematan vs AgregasiMembayangi method yang DisematkanRangkuman: Hierarki Karyawan8Penanganan Error & OOP
Interface errorTipe Error KustomPembungkusan Error (fmt.Errorf)Error Sentinelerrors.Is() dan errors.As()Panic, Defer, dan RecoverRangkuman: Parser File3Pointer dan Memori
Dasar-Dasar Pointer di GoPointer ke StructPass by Value vs ReferenceFungsi new()Garbage Collection di GoRekap: Pembuat Linked List6Polimorfisme di Go
Polimorfisme melalui InterfaceDuck Typing di GoAturan Pemenuhan InterfaceKoleksi PolimorfikInjeksi DependensiRangkuman: Pemroses Pembayaran9Konkruensi & OOP
Dasar-dasar GoroutineChannel & KomunikasiChannel Ber-buffer vs Tanpa BufferPernyataan selectsync.Mutex & sync.RWMutexsync.WaitGroupDesain Struct yang Aman untuk ThreadRingkasan: Worker PoolLatihan sendiri: Compiler Go online