Select

Select #

// Go ရဲ့ *select* က သင့်ကို channel operation အများကြီးကို
// တပြိုင်နက်တည်း စောင့်ဆိုင်းခွင့်ပေးပါတယ်။ Goroutine တွေနဲ့ channel တွေကို
// select နဲ့ ပေါင်းစပ်အသုံးပြုခြင်းဟာ Go ရဲ့ စွမ်းအားကြီးမားတဲ့ feature တစ်ခုဖြစ်ပါတယ်။

package main

import (
	"fmt"
	"time"
)

func main() {

	// ဒီဥပမာမှာ ကျွန်တော်တို့က channel နှစ်ခုကို select လုပ်မှာပါ။
	c1 := make(chan string)
	c2 := make(chan string)

	// Channel တစ်ခုချင်းစီက တန်ဖိုးတစ်ခုကို အချိန်အနည်းငယ်ကြာပြီးမှ လက်ခံရရှိပါမယ်။
	// ဒါဟာ ဥပမာအားဖြင့် concurrent goroutine တွေမှာ အလုပ်လုပ်နေတဲ့
	// blocking RPC operation တွေကို simulate လုပ်တာပါ။
	go func() {
		time.Sleep(1 * time.Second)
		c1 <- "one"
	}()
	go func() {
		time.Sleep(2 * time.Second)
		c2 <- "two"
	}()

	// ကျွန်တော်တို့က `select` ကို သုံးပြီး ဒီတန်ဖိုးနှစ်ခုစလုံးကို တပြိုင်နက်တည်း
	// စောင့်ဆိုင်းမှာဖြစ်ပြီး၊ တန်ဖိုးတစ်ခုချင်းစီ ရောက်လာတိုင်း print ထုတ်ပါမယ်။
	for i := 0; i < 2; i++ {
		select {
		case msg1 := <-c1:
			fmt.Println("received", msg1)
		case msg2 := <-c2:
			fmt.Println("received", msg2)
		}
	}
}
# ကျွန်တော်တို့ မျှော်လင့်ထားတဲ့အတိုင်း 
# `"one"` နဲ့ `"twp"`
#  ဆိုတဲ့တန်ဖိုးတွေကို လက်ခံရရှိပါတယ်။
$ time go run select.go 
received one
received two

# သတိပြုရမှာက စုစုပေါင်း run time က 
# ~2 စက္ကန့်လောက်ပဲ ကြာပါတယ်။
# ဘာကြောင့်လဲဆိုတော့ 1 စက္ကန့် နဲ့ 
# 2 စက္ကန့် `Sleep` နှစ်ခုစလုံးက
# တပြိုင်နက်တည်း (concurrently) 
# အလုပ်လုပ်နေလို့ပါ။
real	0m2.245s