کانالها (Channels)
ارتباط امن بین Goroutine ها با Channel: ارسال، دریافت، buffered و بستن.
Channel چیست؟
Channel لولهای است که Goroutine ها از طریق آن داده رد و بدل میکنند — بهجای اشتراک حافظه، پیاممحور!
«حافظه را به اشتراک نگذارید؛ از طریق ارتباط، حافظه را به اشتراک بگذارید» — شعار Go
ساخت Channel
ch := make(chan string) ← کانال رشتهای
ارسال و دریافت
ch <- "سلام" ← ارسال به کانال
msg := <-ch ← دریافت از کانال
مثال پایه
func main() {
ch := make(chan string)
go func() {
ch <- "سلام از goroutine!" ← ارسال
}()
msg := <-ch ← دریافت (صبر میکند تا داده بیاید)
fmt.Println(msg)
}
همگامسازی داخلی!
- ارسال به کانال خالی بلاک میشود تا کسی دریافت کند
- دریافت از کانال پر بلاک میشود تا داده بیاید
یعنی Channel خودش همگامسازی میکند — بدون قفل دستی!
Buffered Channel — با ظرفیت
ch := make(chan int, 3) ← بافر ۳تایی
ch <- 1 ← بدون بلاک (جا دارد)
ch <- 2
ch <- 3
// ch <- 4 ← بلاک میشود (بافر پر است!)
بستن Channel
close(ch) ← دیگر ارسال نمیشود
تشخیص بسته شدن
value, ok := <-ch
if !ok {
fmt.Println("کانال بسته شده!")
}
پیمایش کانال با for range
go func() {
for i := 1; i <= 5; i++ {
ch <- i
}
close(ch) ← حتماً ببندید تا حلقه تمام شود
}()
for num := range ch { ← تا بسته شدن کانال
fmt.Println(num)
}
Channel یکطرفه
func producer(out chan<- int) { ← فقط ارسال
out <- 42
}
func consumer(in <-chan int) { ← فقط دریافت
fmt.Println(<-in)
}
الگوی Pipeline
func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}
func square(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}
// زنجیره: gen → square → خروجی
for v := range square(gen(1, 2, 3)) {
fmt.Println(v) ← 1 4 9
}
بستن کانال فقط توسط فرستنده انجام شود! دریافت از کانال بسته مقدار صفر میدهد، اما ارسال به کانال بسته panic میکند!
این مبحث بخشی از دوره آموزش کامل گو است.