کانال‌ها (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 می‌کند!

این مبحث بخشی از دوره آموزش کامل گو است.

ابزارهای مرتبط