22. Go - Channels

 Channels allow goroutines to communicate with each other. Channels also allow buffering values to use later (pull).


Make a channel:

var channel1 chan string = make(chan string)

// declare channel type and then the type that will be traded between this channel, which is string


var channel1 chan string = make(chan string, 1)

// 1 indicates that the channel has 1 buffer space. it can send/receive 1 msg until it is full


channel1 := make(chan string)

channel1 := make(chan string,1)

// short declaration


Sending a msg:

channel1 <- "MESSAGE"

// left is receiver channel

// right is the message

// channel sending blocks statements because it needs to send.

// pulling from channel also blocks until it receives a value.


Receiving a msg:

msg := <- channel1

// variable is on left (receiver), channel1 value is on right(messenger)

// statement will only run when there is a value waiting in the channel buffer.


channel1 <- <- channel2

// Double arrows used when the channel2 is a sending channel added as a function argument.

// channel2 outputs values, values are added to channel1.


Channel Buffer Size and Capacity:

len(channel) // channel length, or how much values in buffer currently

cap(channel) // buffer capacity


Closing Channel:

close(CHANNELNAME)

// closing locks a channel from receiving anymore data.

// still can read from the channel after its closed.


Examples:

package main

import (
    "fmt"
    "time"
)

func main() {
    var variable string
    channelOne := make(chan string)

    go func() {
        time.Sleep(time.Second * 5)
        channelOne <- "READY"
        fmt.Println("MESSAGE SENT")
    }()

    go func() {
        <-channelOne // this will wait for a value in the channel before executing.
        fmt.Println("IM DONE")
    }()

    fmt.Scanln(&variable)
}



package main

import (
    "fmt"
    "time"
)

func pinger(c chan string) {
    for i := 0; ; i++ {
        c <- "ping"
    }
}
func printer(c chan string) {
    for {
        msg := <-c
        fmt.Println(msg)
        time.Sleep(time.Second * 1)
    }
}
func main() {
    var c chan string = make(chan string)
    go pinger(c)
    go printer(c)
    var input string
    fmt.Scanln(&input)
}

// pinger go routine will send a ping and wait for printer to receiver the ping and finish their function before pinger can continue.

// time.Sleep() lets function delay

// pinger is putting a lot of pings into channel "c", printer is taking pings and printing them out.



package main

import "fmt"

func main() {
    channel := make(chan string, 1)
    channel2 := make(chan string, 1)

    channel <- "hello"
    test := <-channel
    channel2 <- test

    fmt.Println(<-channel2)
}

// string goes into channel, channel sends to test, test sends to channel2.

// nothing is in channel because its value got sent out to test.

// buffer channel


Channel directions for functions:

func pinger(c chan<- string) // pinger only sent out

func printer(c <-chan string) // printer only receive


Select (the channel version of switch cases):

select {
case msg1 := <-c1:
    fmt.Println("Message 1", msg1)
case msg2 := <-c2:
    fmt.Println("Message 2", msg2)
case <-time.After(time.Second):
    fmt.Println("timeout")
}


Comments

Popular posts from this blog

2. FreeCodeCamp - Dynamic Programming - Learn to Solve Algorithmic Problems & Coding Challenges

20. Data Analytics - Analyze Data to Answer Questions - Week 1

3. Algorithms - Selection Sort