channel可以是各种数据类型: (map类型) (struct类型) (接口类型)

package main

import "fmt"

type student struct {
	name string
}

func main() {
	var stuChan chan interface{}
	//空interface类型可以是任意类型
	stuChan = make(chan interface{}, 10)
	stu := student{name:"stu01"}
	stuChan <- &stu

	var stu01 interface{}
	stu01 = <- stuChan

	fmt.Println(stu01)

	var stu02 *student
	//将stu01由interface转换为结构体类型指针
	stu02, ok := stu01.(*student)
	if !ok {
		fmt.Println("不可以转换")
		return
	}
	fmt.Println(stu02)

}

输出: &{stu01} &{stu01}

Process finished with exit code 0

channel关闭,判断:

package main

import "fmt"

func main() {
	var ch chan int
	ch = make(chan int, 10)

	for i := 0; i < 10; i++ {
		ch <- i
	}

	close(ch)

	for {
		var b int
		//从chan取数据的时候第二个参数用来判断是否成功
		b, ok := <- ch
		if ok == false {
			fmt.Println("chan is closed")
			return
		}
		fmt.Println(b)
	}

}

输出: 01 2 3 4 5 6 7 8 9 chan is closed range遍历chan:

package main

import "fmt"

func main() {
	var ch chan int
	ch = make(chan int, 1000)

	for i := 0; i < 1000; i++ {
		ch <- i
	}

	close(ch)
	for v := range ch {
		fmt.Println(v)
	}
}

关闭chan,goroutine同步案例:

package main

import (
	"fmt"
)

func calc(taskChan chan int, resChan chan int,	exitChan chan bool) {
	for v := range taskChan {
		flag := true
		for i := 2; i < v; i++ {
			if v%i == 0 {
				flag = false
				break
			}
		}

		if flag {
			resChan <- v
		}
	}

	fmt.Println("exit")
	//每个calc的协程(goroutine)结束后写入true到名为exitChan的chan里。代表该goroutine结束了
	exitChan <- true
}

func main() {
	intChan := make(chan int, 1000)
	resultChan := make(chan int, 1000)
	exitChan := make(chan bool, 8)

	go func() {
		for i := 0; i < 10000; i++ {
			intChan <- i
		}

		close(intChan)
	}()

	for i := 0; i < 8; i++ {
		go calc(intChan, resultChan, exitChan)
	}

	//等待所有计算的goroutine全部退出
	go func() {
		for i := 0; i < 8; i++ {
			<-exitChan
			fmt.Println("wait goroute ", i, " exited")
		}
		//8个goroutine结束后关闭resultChan管道
		close(resultChan)
	}()

	//resultChan管道关闭后,range才能在遍历完后结束
	for v := range resultChan {
		fmt.Println(v)
	}
}

再来个同步channel的例子:

package main

import (
	"fmt"
)

func send(ch chan int, exitChan chan bool) {
	for i := 0; i < 10; i++ {
		ch <- i
	}
	close(ch)
	exitChan <- true
}

func recv(ch chan int, exitChan chan bool) {
	for {
		v, ok := <- ch
		if !ok {
			break
		}
		fmt.Println(v)
	}
	exitChan <- true
}

func main() {
	ch := make(chan int, 10)
	exitChan := make(chan bool, 2)

	go send(ch, exitChan)
	go recv(ch, exitChan)

	var total = 0
	for _ = range exitChan {
		total++
		if total == 2 {
			break
		}
	}

}

输出: 01 2 3 4 5 6 7 8 9

Process finished with exit code 0 channel的只读,只写(读函数里只准读,写函数里只准写。来进行规范,防止出错):

package main

import "fmt"

func send(ch chan<- int, exitChan chan struct{}) {

	for i := 0; i < 10; i++ {
		ch <- i
	}

	close(ch)
	var a struct{}
	exitChan <- a
}

func recv(ch <-chan int, exitChan chan struct{}) {
	for {
		v, ok := <-ch
		if !ok {
			break
		}

		fmt.Println(v)
	}

	var a struct{}
	exitChan <- a
}

func main() {
	var ch chan int
	ch = make(chan int, 10)
	exitChan := make(chan struct{}, 2)

	go send(ch, exitChan)
	go recv(ch, exitChan)

	var total = 0
	for _ = range exitChan {
		total++
		if total == 2 {
			break
		}
	}
}