Pernyataan select
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 62 dari 107.
Pernyataan select memungkinkan goroutine menunggu beberapa operasi channel secara bersamaan. Pernyataan ini mirip dengan pernyataan switch, tetapi setiap kasus melibatkan pengiriman atau penerimaan melalui channel. Saat beberapa channel siap, select memilih salah satunya secara acak.
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() { ch1 <- "from channel 1" }()
go func() { ch2 <- "from channel 2" }()
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
}
}Tanpa select, menerima dari ch1 akan memblokir hingga data tiba, sehingga data di ch2 mungkin terlewat. Dengan select, channel mana pun yang menerima data lebih dulu akan ditangani.
Case default membuat select tidak memblokir. Case ini langsung dijalankan jika tidak ada channel yang siap:
select {
case msg := <-messages:
fmt.Println("Received:", msg)
default:
fmt.Println("No message available")
}Pola umum menggabungkan select dengan batas waktu menggunakan time.After, yang mengembalikan channel yang menerima nilai setelah durasi yang ditentukan:
select {
case result := <-ch:
fmt.Println("Got result:", result)
case <-time.After(2 * time.Second):
fmt.Println("Timeout!")
}Ini mencegah programmu menunggu selamanya saat operasi channel mungkin tidak pernah selesai.
Tantangan
MudahMari buat monitor layanan yang menggunakan pernyataan select untuk menangani beberapa sumber data konkuren. Monitor kamu akan mendengarkan berbagai channel layanan secara bersamaan dan merespons dengan tepat saat data tiba atau saat tidak ada pembaruan.
Kamu akan mengatur kodemu dalam dua file:
monitor.go: Definisikan logika pemantauan layanan dengan penanganan channel berbasis select.Buat struct
ServiceUpdatedengan fieldName(string) danStatus(string).Implementasikan fungsi
Monitoryang menerima tiga channel:primary chan ServiceUpdate,backup chan ServiceUpdate, dandone chan bool. Fungsi ini harus menggunakanselectuntuk mendengarkan ketiga channel secara bersamaan:- Saat menerima dari
primary: kembalikan string berformatPrimary: [Name] is [Status] - Saat menerima dari
backup: kembalikan string berformatBackup: [Name] is [Status] - Saat menerima dari
done: kembalikanMonitoring stopped
Implementasikan fungsi
CheckStatusyang menerima satuupdates chan ServiceUpdatedan menggunakanselectdengan kasusdefaultuntuk melakukan pemeriksaan non-blocking:- Jika ada pembaruan: kembalikan
Update available: [Name] - Jika tidak ada pembaruan (kasus default): kembalikan
No updates pending
- Saat menerima dari
main.go: Siapkan channel dan tunjukkan perilaku select blocking dan non-blocking.Baca mode dari input untuk menentukan skenario yang dijalankan:
primary,backup,stop, ataucheck.Untuk mode
primary,backup, danstop: baca juga nama dan status layanan. Buat tiga channel, jalankan goroutine yang mengirim data ke channel yang sesuai berdasarkan mode, lalu panggilMonitordan cetak hasilnya.Untuk mode
check: baca nama dan status layanan, serta flag (sendataunosend) yang menunjukkan apakah data dikirim sebelum pemeriksaan. Buat channel buffered dengan kapasitas 1. Jika flag-nyasend, kirim pembaruan ke channel sebelum memanggilCheckStatus. Cetak hasilCheckStatus.
Input berikut akan diberikan:
- Baris 1: Mode (
primary,backup,stop, ataucheck) - Baris 2: Nama layanan
- Baris 3: Status layanan
- Baris 4 (hanya untuk mode
check):sendataunosend
Sebagai contoh, jika diberikan:
primary
Database
healthyOutput kamu seharusnya:
Primary: Database is healthyDan jika diberikan:
check
Cache
active
nosendOutput kamu seharusnya:
No updates pendingCoba sendiri
package main
import (
"fmt"
)
func main() {
var mode string
fmt.Scanln(&mode)
var serviceName string
fmt.Scanln(&serviceName)
var serviceStatus string
fmt.Scanln(&serviceStatus)
// TODO: Tangani berbagai mode: "primary", "backup", "stop", "check"
// Untuk mode "primary", "backup", "stop":
// - Buat tiga channel: primary, backup, done
// - Jalankan goroutine yang mengirim data ke channel yang sesuai
// - Panggil Monitor dan cetak hasilnya
// Untuk mode "check":
// - Baca flag tambahan ("send" atau "nosend")
// - Buat channel dengan buffer berkapasitas 1
// - Jika flag bernilai "send", kirim pembaruan ke channel
// - Panggil CheckStatus dan cetak hasilnya
}
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