Golang Channel is Collection Type part 1

ภาษาโก มีประเภทข้อมูลที่ชื่อว่า Channel ที่ถูกออกแบบมาไว้สำหรับเก็บข้อมูลที่จะถูกใช้ร่วมกันระหว่างหลาย Goroutine ซึ่ง operator ที่เอาไว้ทำงานกับ ข้อมูลแบบ Channel มีหลักๆ 2 operators ด้วยกันคือ รับค่าจาก Channel และ ส่งค่าเข้าไปเก็บใน Channel จริงๆทั้ง 2 operators นี้ใช้สัญลักษณ์เดียวกันคือ <- ต่างกันแค่เราวางตัวแปร Channel ไว้ด้านไหน เช่น ถ้าให้ ch เป็นตัวแปรของ channel

ch <- val // คือการส่งค่า val เข้าไปใน channel ch

val <- ch // คือการเอาค่าออกมาจาก channel ch

การสร้างตัวแปร และ สร้างข้อมูลแบบ Channel

การสร้างตัวแปรประเภทข้อมูลแบบ Channel เราจะใช้ keyword คำว่า “chan” เว้นวรรคแล้วตามด้วยชื่อประเภทข้อมูลที่เราสามารถส่งข้อมูลเข้าไปใน Channel ได้ เช่น

var ch chan int

เป็นการสร้างตัวแปร ch ที่มีประเภทข้อมูลคือ chan int คือประเภทแบบ channel ของ int จะส่งข้อมูลเข้าออก ch ได้เฉพาะข้อมูลแบบ int เท่านั้น

ถ้าเราสร้างค่าตัวแปรเฉยๆ โดยยังไม่สร้างค่าของ channel กำหนดให้กับตัวแปร ค่าเริ่มต้นจะเป็น nil

การสร้างค่าของ channel จะใช้ฟังก์ชัน make โดย argument แรกเป็น type ส่วน argument ที่สองเป็นจำนวน buffer ซึ่งถ้าเราไม่ใส่ channel นี่จะเป็นแบบ unbuffer ซึ่งจะมีพฤติกรรมการทำงานที่ต่างกัน เดี๋ยวอธิบายทีหลังอีกที ตัวอย่างการสร้างค่า channel เช่น

var ch chan int = make(chan int) // unbuffer

ch := make(chan int, 1) // one buffer

พฤติกรรมการทำงานของ Channel แบบ Unbuffer

เมื่อเรากระทำการ รับ และ ส่ง ข้อมูลกับ Channel แบบ Unbuffer จะเกิดการ block การทำงานที่คำสั่งการส่งและรับ จนกว่าจะมีการรับและส่ง ที่เกิดขึ้นแยกออกจากกันคนละ Goroutine (Concurrent) การทำงานถึงจะขยับไปยังบรรทัดถัดไป เช่น

package main
import "fmt"
func main() {
ch := make(chan int)
 // send
go func() {
ch <- 10
}()
 // receive
val := <-ch
fmt.Println(val)
}

ถ้าเรามีแต่ส่ง ไม่มีรับ หรือมีแต่รับ ไม่มีส่งเลย จะให้เกิดการ block ไม่ไปไหน (deadlock)

part 1 จบที่การทำงานของ Unbuffer ก่อน คราวหน้ามาดู พฤติกรรมการทำงานของ Channel แบบมี Buffer กัน