go如何实现深拷贝?
import (
"bytes"
"encoding/gob"
"fmt"
)
func deepCopy(dst, src interface{}) error {
var buf bytes.Buffer
if err := gob.NewEncoder(&buf).Encode(src); err != nil {
return err
}
return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
}
两个协程交替打印奇偶数
//两个协程交替打印奇偶数
func main(){
flagChan:=make(chan struct{}) //无缓冲chan
go func() {
for i:=1;i<=10;i++{
flagChan<- struct{}{}
if i&1==1{
fmt.Println("goroutine one:",i)
}
}
}()
go func() {
for i:=1;i<=10;i++{
<-flagChan
if i&1==0{
fmt.Println("gorroutine two:",i)
}
}
}()
time.Sleep(3*time.Second)
}
两个协程循环打印字母和数字
//两个协程轮流打印数字和字母 A 1 B 2 C 3 .... Z 26
func main(){
Buffer() //有缓冲的方式
NoBuffer() //无缓冲的方式
}
//有缓冲区的chan循环打印.
func Buffer(){
strChan:=make(chan struct{},1)
numChan:=make(chan struct{},1)
//先向numChan中放入作为开启
numChan<- struct{}{}
go func(){
for i:='A';i<='Z';i++{
<-numChan //读取之后才能继续
fmt.Printf("%v ",string(i))
strChan<- struct{}{}
}
}()
go func() {
for i:=1;i<=26;i++{
<-strChan
fmt.Printf("%v ",i)
numChan<- struct{}{} //通知数字打印完毕
}
}()
time.Sleep(3*time.Second)
}
//无缓冲的chan实现方式
func NoBuffer(){
//
strChan:=make(chan struct{})
numChan:=make(chan struct{})
go func(){
for i:='A';i<='Z';i++{
fmt.Printf("%v ",string(i))
strChan<- struct{}{}
<-numChan //读取之后才能继续
}
}()
go func() {
for i:=1;i<=26;i++{
<-strChan
fmt.Printf("%v ",i)
numChan<- struct{}{} //通知数字打印完毕
}
}()
time.Sleep(3*time.Second)
}
N个协程循环打印1-100
//N个协程交替打印1-100
const NUM = 5 //假设5个协程交替打印
func main(){
exitChan:=make(chan int,1) //退出的标识
chanNums:=make([]chan int,0) //chan数组 ,开启多个协程哪个对应的chan到达则可以运行
res:=1 //全局res,因为交替打印,多协程操作也不需要加锁
index:=0 //协程标识,到达NUM重新归零
for i:=0;i<NUM;i++{ //初始化对应的chan
chanNums = append(chanNums,make(chan int,1))
}
for i:=0;i<NUM;i++{
go func(i int) { //开启NUM个协程
for { //循环打印
<-chanNums[i] //对应的chan存在数据才打印
if res>100{ //越界退出
exitChan<-1
break
}
fmt.Println("goroutine",i, "res:",res)
res++
index = (index+1)%NUM //5个协程index为0,1,2,3,4 到达4之后重新归零
chanNums[index]<-1 //放入下一个
}
}(i)
}
//初始化时候先把第一个打印goroutine开启
chanNums[0]<-1
//退出标识存在才会退出
select {
case <-exitChan:
fmt.Println("main终止")
}
}