0Pricing
Go Academy · Pelajaran

Channel Tanpa Buffer

Serah-terima sinkron antar-goroutine

Channel Tanpa Buffer adalah pelajaran Go Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Go Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Go Academy mencakup 4 pelajaran total.

Apa Itu Saluran?

saluran adalah media bertipe untuk berkomunikasi antar-goroutine. Saluran mengikuti prinsip Go: Jangan berkomunikasi dengan berbagi memori; bagikan memori dengan berkomunikasi.

package main
import "fmt"

func main() {
    ch := make(chan int)   // unbuffered int channel

    go func() {
        ch <- 42  // send: blocks until someone receives
    }()

    v := <-ch  // receive: blocks until someone sends
    fmt.Println(v) // 42
}

Semantik Saluran Tanpa Penyangga

Saluran tanpa penyangga tidak memiliki kapasitas. Pengiriman terblokir sampai receiver siap, dan penerimaan terblokir sampai sender mengirim. Ini menyediakan serah terima sinkron yang terjamin:

package main
import "fmt"

func double(in <-chan int, out chan<- int) {
    for v := range in {
        out <- v * 2
    }
    close(out)
}

func main() {
    in := make(chan int)
    out := make(chan int)
    go double(in, out)
    go func() { in <- 3; in <- 5; close(in) }()
    for v := range out { fmt.Println(v) }
    // 6
    // 10
}

Saluran sebagai Sinkronisasi

Saluran tanpa penyangga menyinkronkan goroutine — gunakan sebagai sinyal bahwa pekerjaan telah selesai:

package main
import "fmt"

func compute(result chan<- int) {
    sum := 0
    for i := 1; i <= 100; i++ { sum += i }
    result <- sum
}

func main() {
    ch := make(chan int)
    go compute(ch)
    fmt.Println("Result:", <-ch) // blocks until compute sends
}

Menutup Saluran

Sender menutup saluran dengan close(ch) untuk menandakan bahwa tidak ada lagi nilai yang akan dikirim. Penerima mendeteksi penutupan melalui bentuk dua nilai:

package main
import "fmt"

func generate(ch chan<- int, max int) {
    for i := 0; i < max; i++ {
        ch <- i
    }
    close(ch)  // signal done
}

func main() {
    ch := make(chan int)
    go generate(ch, 5)

    for v := range ch {  // range detects close automatically
        fmt.Println(v)
    }
    fmt.Println("channel closed")
}

Penerimaan Dua Nilai

Penerimaan dua nilai v, ok := <-ch memberi tahu Anda apakah saluran masih terbuka:

package main
import "fmt"

func main() {
    ch := make(chan string, 1)
    ch <- "hello"
    close(ch)

    v1, ok1 := <-ch
    fmt.Println(v1, ok1)  // hello true

    v2, ok2 := <-ch
    fmt.Println(v2, ok2)  // "" false — channel closed
}

Mengirim pada Saluran Tertutup Menyebabkan Kepanikan

Mengirim ke saluran yang sudah ditutup menyebabkan kepanikan. Hanya sender yang boleh menutup saluran — jangan pernah receiver:

package main
import "fmt"

func main() {
    ch := make(chan int)
    close(ch)

    // Receiving from closed channel returns zero value
    v, ok := <-ch
    fmt.Println(v, ok)  // 0 false

    // Sending to closed channel panics:
    defer func() { recover() }()
    ch <- 1  // panic: send on closed channel
}

Saluran Searah

Batasi saluran menjadi hanya-pengiriman (chan<- T) atau hanya-penerimaan (<-chan T) dalam tanda tangan fungsi agar lebih jelas dan aman:

package main
import "fmt"

func producer(out chan<- int) {  // send-only
    for i := 0; i < 3; i++ { out <- i }
    close(out)
}

func consumer(in <-chan int) {   // receive-only
    for v := range in { fmt.Println(v) }
}

func main() {
    ch := make(chan int)
    go producer(ch)
    consumer(ch)
}

Goroutine dan Saluran yang Saling Mengirim

Dua goroutine yang saling mengirim pesan melalui saluran — contoh klasik sinkronisasi:

package main
import "fmt"

func ping(ping, pong chan struct{}) {
    for i := 0; i < 3; i++ {
        <-ping
        fmt.Println("ping")
        pong <- struct{}{}
    }
}

func main() {
    ping := make(chan struct{})
    pong := make(chan struct{})
    go func() { for { <-pong; fmt.Println("pong"); ping <- struct{}{} } }()
    go func() { for i := 0; i < 3; i++ { ping <- struct{}{}; <-pong } }()
    // Simplified version:
    fmt.Println("channels enable structured communication")
}

Saluran nil Memblokir Selamanya

Menerima dari atau mengirim ke saluran nil akan terblokir selamanya. Hal ini terkadang digunakan secara sengaja dalam pernyataan select:

package main
import "fmt"

func main() {
    var ch chan int  // nil channel
    fmt.Println(ch == nil) // true

    // select with nil channel — that case is never selected
    active := make(chan int, 1)
    active <- 42
    select {
    case v := <-ch:      // never selected (nil)
        fmt.Println(v)
    case v := <-active:  // selected
        fmt.Println("got:", v)
    }
}

Kapan Menggunakan Saluran Tanpa Penyangga

Gunakan saluran tanpa penyangga ketika:

  • Anda memerlukan serah terima sinkron yang terjamin
  • Goroutine harus mengakui penerimaan sebelum sender melanjutkan
  • Menerapkan semafor atau tekanan balik
  • Membuat alur yang setiap tahapnya harus memproses satu elemen pada satu waktu

Pemeriksaan Singkat

Apa yang terjadi ketika Anda mengirim pada saluran tanpa penyangga yang belum memiliki receiver siap?

Ringkasan: Saluran Tanpa Penyangga

Ringkasan:

  • Buat dengan make(chan T) — kapasitas nol
  • Pengiriman terblokir sampai receiver siap; penerimaan terblokir sampai sender mengirim
  • Hanya sender yang boleh menutup saluran
  • range ch melakukan iterasi sampai saluran ditutup
  • Penerimaan dua nilai: v, ok := <-ch
  • Gunakan tipe searah agar lebih jelas: chan<- dan <-chan

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Channel Tanpa Buffer” gratis?

Ya — teks lengkap “Channel Tanpa Buffer” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Go Academy, upgrade ke CoddyKit PRO. Kursus Go Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Channel Tanpa Buffer”?

Serah-terima sinkron antar-goroutine Kamu berlatih Go Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Go Academy?

Tidak diperlukan pengalaman sebelumnya. Go Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Channel Tanpa Buffer” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Go Academy ini?

Ya. Setiap pelajaran Go Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Menjalankan Goroutine
  2. Channel Tanpa Buffer
  3. Channel Berbuffer
  4. Arah Channel dan Pola Pipeline
← Kembali ke Go Academy