Channel & Komunikasi
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 60 dari 107.
Channels adalah mekanisme utama Go untuk komunikasi antara goroutine. Alih-alih berbagi memori secara langsung, goroutine mengirim dan menerima nilai melalui channel, mengikuti filosofi Go: "Jangan berkomunikasi dengan berbagi memori; berbagi memori dengan berkomunikasi."
Buat saluran menggunakan fungsi make dengan kata kunci chan:
messages := make(chan string)Gunakan operator panah <- untuk mengirim dan menerima nilai. Panah menunjukkan arah aliran data:
func main() {
messages := make(chan string)
go func() {
messages <- "hello" // kirim ke channel
}()
msg := <-messages // terima dari channel
fmt.Println(msg) // output: hello
}Secara default, mengirim dan menerima block sampai pihak lain siap. Saat goroutine mengirim "hello", goroutine itu menunggu sampai main siap menerima. Perilaku pemblokiran ini menyediakan sinkronisasi bawaan: tidak perlu time.Sleep.
Kamu dapat menutup channel untuk memberi sinyal bahwa tidak ada lagi nilai yang akan dikirim. Penerima dapat mendeteksinya:
close(messages)
msg, ok := <-messages
if !ok {
fmt.Println("Channel closed")
}Channel memiliki tipe: chan string hanya dapat membawa string. Keamanan tipe ini memastikan goroutine berkomunikasi menggunakan tipe data yang tepat, sehingga error terdeteksi saat kompilasi, bukan saat runtime.
Tantangan
MudahMari bangun sistem relay pesan yang menunjukkan cara goroutine berkomunikasi melalui channel. Kamu akan membuat pipeline tempat pesan mengalir di antara berbagai tahap pemrosesan, dengan setiap tahap berjalan secara bersamaan.
Kamu akan mengatur kodemu dalam dua file:
relay.go: Definisikan pipeline pemrosesan pesanmu.Buat struct
Messagedengan fieldID(int) danContent(string).Buat tiga fungsi yang mewakili berbagai tahap pipeline-mu:
Producer(messages []Message, out chan Message)- Menerima slice pesan dan mengirim setiap pesan ke channel output. Setelah mengirim semua pesan, tutup channel untuk menandakan bahwa proses selesai.Transformer(in chan Message, out chan Message)- Menerima pesan dari channel input, mengubah konten setiap pesan menjadi huruf kapital, lalu mengirim pesan yang sudah diubah ke channel output. Saat channel input ditutup, yang dideteksi menggunakan bentuk penerimaan dua nilai, tutup channel output.Consumer(in chan Message) []string- Menerima semua pesan dari channel input dan mengumpulkannya ke dalam slice string berformat. Setiap string harus mengikuti format:Message [ID]: [Content]. Kembalikan slice saat channel ditutup.
main.go: Siapkan pipeline dan atur aliran pesan yang berjalan secara bersamaan.Baca jumlah pesan, lalu baca ID dan konten setiap pesan. Buat pesan-pesan tersebut dan siapkan dua channel untuk menghubungkan tiga tahap pipeline. Jalankan Producer dan Transformer sebagai goroutine, lalu jalankan Consumer di goroutine utama untuk mengumpulkan hasil. Cetak setiap hasil pada baris terpisah.
Input berikut akan diberikan:
- Baris 1: Jumlah pesan (integer)
- Baris berikutnya: Untuk setiap pesan, dua baris, yaitu ID pesan (integer), lalu kontennya (string)
Contohnya, jika diberikan:
2
1
hello world
2
go channelsOutput-mu seharusnya:
Message 1: HELLO WORLD
Message 2: GO CHANNELSAliran pipeline berjalan seperti ini: Producer mengirim pesan → Transformer mengubahnya menjadi huruf kapital → Consumer mengumpulkan dan memformat hasil. Setiap panah mewakili channel yang menghubungkan tahap-tahap yang berjalan secara bersamaan. Gunakan package strings untuk mengubah teks menjadi huruf kapital.
Coba sendiri
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Baca jumlah pesan
nLine, _ := reader.ReadString('\n')
n, _ := strconv.Atoi(strings.TrimSpace(nLine))
// Baca pesan
messages := make([]Message, n)
for i := 0; i < n; i++ {
idLine, _ := reader.ReadString('\n')
id, _ := strconv.Atoi(strings.TrimSpace(idLine))
contentLine, _ := reader.ReadString('\n')
content := strings.TrimSpace(contentLine)
messages[i] = Message{ID: id, Content: content}
}
// TODO: Buat dua channel untuk menghubungkan tahap-tahap pipeline
// TODO: Jalankan Producer sebagai goroutine
// TODO: Jalankan Transformer sebagai goroutine
// TODO: Jalankan Consumer di goroutine utama dan kumpulkan hasilnya
// TODO: Cetak setiap hasil pada baris terpisah
}
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