This is the 25th day of my participation in the August Genwen Challenge.More challenges in August

Scope loops on channels

We can loop in data from the channel until the channel is closed. The for-range form of the for loop can be used to receive values from the channel until it closes.

Example code for using the range loop:

package main

import (
	"time"
	"fmt"
)

func main(a)  {
	ch1 :=make(chan int)
	go sendData(ch1)
	// The for range form of the for loop can be used to receive values from the channel until it closes.
	for v := range ch1{
		fmt.Println("Read data:",v)
	}
	fmt.Println("main.. over.....")}func sendData(ch1 chan int)  {
	for i:=0; i<10 ; i++ {
		time.Sleep(1*time.Second)
		ch1 <- i
	}
	close(ch1)// Notify the other party that the channel is closed
}
Copy the code

Running results:

Unbuffered channel

All of the channels we’ve learned so far are essentially unbuffered. Sending and receiving to an unbuffered channel is blocked.

A send operation corresponds to a receive operation. For one goroutine, a send is blocked until another goroutine receives it. Similarly, for receiving, it is blocked until another Goroutine is sent.

Buffer channel

A buffer channel is a channel with a buffer. Sending to a buffer channel is blocked only if the buffer is full. Similarly, information received from the buffer channel is blocked only if the buffer is empty.

The buffer channel can be created by passing an additional capacity argument to the make function, which specifies the size of the buffer.

Grammar:

ch := make(chan type, capacity)  
Copy the code

The capacity of the above syntax should be greater than 0 so that the channel has buffers. By default, the capacity of the unbuffered channel is 0, so the capacity parameter was omitted when the channel was created earlier.

Sample code:

In the following code, the chan channel is buffered.

package main

import (
	"fmt"
	"strconv"
	"time"
)

func main(a) {
	/* make(chan T,size) make(chan T,size) queue * /
	ch1 := make(chan int)           // Uncached channel
	fmt.Println(len(ch1), cap(ch1)) / / 0 0
	// If CH1 < -100 // blocks, another goroutine is needed to remove the block, otherwise the deadlock will be left

	ch2 := make(chan int.5)        // Cache channel, cache size is 5
	fmt.Println(len(ch2), cap(ch2)) / / 0 5
	ch2 <- 100                      //
	fmt.Println(len(ch2), cap(ch2)) / / 1 5

	//ch2 <- 200
	//ch2 <- 300
	//ch2 <- 400
	//ch2 <- 500
	//ch2 <- 600
	fmt.Println("-- -- -- -- -- -- -- -- -- -- -- -- -- -")
	ch3 := make(chan string.4)
	go sendData3(ch3)
	for {
		time.Sleep(1*time.Second)
		v, ok := <-ch3
		if! ok { fmt.Println("Yes, I have.", ok)
			break
		}
		fmt.Println("\t读取的数据是:", v)
	}

	fmt.Println("main... over...")}func sendData3(ch3 chan string) {
	for i := 0; i < 10; i++ {
		ch3 <- "Data" + strconv.Itoa(i)
		fmt.Println("Child goroutine, write the first.", i, "A number.")}close(ch3)
}
Copy the code

Running results:

Two-way channel

Channels, channels, are used to communicate between goroutines. One Goroutine can send data to a channel, and another goroutine can fetch data from that channel. So far we have studied channels that can both send data and read data, and we call this channel a two-way channel.

data := <- a // read from channel a  
a <- data // write to channel a
Copy the code
A one-way passage

A one-way channel is a directional channel.

The channels we’ve been studying are two-way channels through which we can receive and send data. We can also create one-way channels that can only send or receive data.

Two-way channel, example code:

package main

import "fmt"

func main(a)  {
	/* Two-way: chan T --> chan < -data, write data, write data < -chan, get data, read one-way: directed chan < -t, only support write, < -chan T, read-only */
	ch1 := make(chan string) // Two-way, readable, writable
	done := make(chan bool)
	go sendData(ch1, done)
	data :=<- ch1 / / blocking
	fmt.Println("The son goroutine came:", data)
	ch1 <- "I'm Main..." / / blocking

	<-done
	fmt.Println("main... over....")}// Subgoroutine --> write data to ch1 channel
//main goroutine--> fetch from ch1 channel
func sendData(ch1 chan string, done chan bool)  {
	ch1 <- "I'm Xiao Ming."/ / blocking
	data := <-ch1 / / blocking
	fmt.Println("Main Goroutine comes:",data)

	done <- true
}
Copy the code

Running results:

Example code for creating a channel that can only send data:

Sample code:

package main

import "fmt"

func main(a)  {
	/* One-way: directed chan < -t, write only, < -chan T, read-only for parameter passing: */
	ch1 := make(chan int)// Two-way, read, write
	//ch2 := make(chan < -int) //
	//ch3 := make(< -chan int) //
	//ch1 <- 100
	//data :=<-ch1
	//ch2 <- 1000
	//data := <- ch2
	//fmt.Println(data)
	//	<-ch2 //invalid operation: <-ch2 (receive from send-only type chan<- int)
	//ch3 <- 100
	//	<-ch3
	//	ch3 <- 100 //invalid operation: ch3 <- 100 (send to receive-only type <-chan int)

	//go fun1(ch2)
	go fun1(ch1)
	data:= <- ch1
	fmt.Println("The data written in fun1 is:",data)

	//fun2(ch3)
	go fun2(ch1)
	ch1 <- 200
	fmt.Println("main。。over。。")}// This function receives, write-only channels
func fun1(ch chan <- int){
	// Inside the function, only write data to ch, not read data
	ch <- 100
	fmt.Println("The fun1 function ends...")}func fun2(ch <-chan int){
	// Inside the function, ch can only read data, not write data
	data := <- ch
	fmt.Println(The fun2 function reads the following data from ch:,data)
}
Copy the code

Running results: