Comma Ok İdiom

Bir önceki derste kapalı kanaldan sürekli 0 okuduğumuzu görmüştük. Kapalı kanallardan veri okuyunca o kanalın tuttuğu türün sıfır değerini, örneğin int türler için 0 görürüz. Peki bir kanalı okduğumuz zaman kanaldaki veri gerçekten mi 0 yoksa kapalı bir kanalı okduğumuz için mi böyle oluyor, bunu nasıl ayıracağız? İşte bunu göreceğiz şimdi.

Aşağıdaki koda bakalım:

package main

import "fmt"

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

	go tx(ch)
	rx(ch)
	fmt.Println("Çıkış yapıyoruz.")
}

func tx(ch chan<- int) {
	for i := 0; i < 10; i++ {
		ch <- i
	}
	close(ch)
}

func rx(ch <-chan int) {
	i := 0
	for {
		select {
		case v := <-ch:
			fmt.Println(v)
		}
		i += 1
		if i > 100 {
			return
		}
	}
}

Bir öncekine benzer bir kod yazdık, sadece tek kanallı. Burada rx() fonksiyonu tek kanalı aslında dinliyor ve değer oldukça onu tüketiyor. Çıktısı ise şu şekilde:

0
1
2
3
4
5
6
7
8
9
0
0
.
.
0

İlk başlarda her şey doğru gözükse de tx() tarafından kanal kapatılınca kanal artık sürekli 0 basıyor ve aslında rx() içerisinde sonsuz bir döngü oluşuyor. O oluşmasın diye rx() içerisine de bir counter koydum.

Şimdi comma ok idiomu kullanalım:

package main

import "fmt"

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

	go tx(ch)
	rx(ch)
	fmt.Println("Çıkış yapıyoruz.")
}

func tx(ch chan<- int) {
	for i := 0; i < 10; i++ {
		ch <- i
	}
	close(ch)
}

func rx(ch <-chan int) {
	for {
		select {
		case v, ok := <-ch:
			if ok {
				fmt.Println(v)
			} else {
				fmt.Println("Aa! Kanal kapanmış :(")
				return
			}

		}
	}
}

Çıktı:

0
1
2
3
4
5
6
7
8
9
Aa! Kanal kapanmış :(
Çıkış yapıyoruz.

case v, ok := <-ch şeklinde kullanım comma ok idiom olarak geçiyor. Burada ok değerine bakarak kanaldan okuduğumuz verinin geçerli olup olmadığını anlıyoruz. Bu kullanımda aslında kanalın kapandığını anlıyoruz ve kapalı kanaldan okuduğumuz verileri dikkate almıyoruz. Ayrıca rx() fonksiyonumuzun sonlanması için kullanıyoruz.

Peki Go’da kapanmış kanallar tekrar açılamaz mı? Yaptığım araştırmalara göre hayır. O yüzden kapalı gördüğümüz bir kanalın ömrünün bittiğini düşünebiliriz.