Channels in Golang

  • 本文关键字:Golang in Channels go
  • 更新时间 :
  • 英文 :


我正在尝试实现一个函数,该函数使用通道向另一个函数发送数量不确定的变量(类型float64(。

第二个函数将接收并创建一个与接收顺序相关的切片。

这是在我已经开发的系统中再添加一个功能的练习。这就是为什么代码是这样表述的。

当缓冲区为1时,程序进入死锁。如果我把它增加到7(=切片长度(,程序就会运行错误并且不会停止。

我知道缓冲区应该等于0或不大于1,以确保不会丢失数据和顺序。

https://play.golang.org/p/rnLH51GinsG

我希望你能帮助我。

package main
import (
"fmt"
"sync"
)
var waitgroup sync.WaitGroup
/* This function simulates another that sends an
undetermined amount of float64.*/
func sendFloat64() <-chan float64 {
channel := make(chan float64, 7) // Buffer = 1 to ensure receipt of the first data before sending the second
defer close(channel)
originalSlice := []float64{90, 180, 270, 300, 330, 358, 359} // It represents an undetermined number of values.
for _, v := range originalSlice {
channel <- v // one value at a time to keep order
fmt.Println("SendFloat64: send data to channel", v)
}
return channel
}
/* This function receives the values and then it will be
incorporated in a slice respecting the order in which they were sent.*/
func RecreateSlice() <-chan []float64 {
waitgroup.Add(1)
defer waitgroup.Done()
channelOut := make(chan []float64)
defer close(channelOut)
var slice []float64
for {
dataRecived, ok := <-sendFloat64()
if !ok {
break
}
fmt.Println("RecreateSlice: Data received from channel", dataRecived)
slice = append(slice, dataRecived)
}
channelOut <- slice
return channelOut
}
func main() {
go RecreateSlice()
PM := <-RecreateSlice()
fmt.Println("Printed in main", PM)
waitgroup.Wait()
}

如果我正确理解你的问题,我认为这段代码更好。它也保证了订单。

package main
import (
"fmt"
)
// sendFloat64 simulates another that sends an
// undetermined amount of float64.
func sendFloat64(ch chan<- float64) {
originalSlice := []float64{90, 180, 270, 300, 330, 358, 359}
for _, v := range originalSlice {
// send the data in order as soon as possible to the reciver
ch <- v
fmt.Println("SendFloat64: send data to channel", v)
}
close(ch)
}
// RecreateSlice receives the values and then it will be
// incorporated in a slice respecting the order in which they were sent.
func RecreateSlice() []float64 {
var stream []float64
// Create a float64 channel with a buffer of 1
channel := make(chan float64, 1)
go sendFloat64(channel)
// Append data until the channel is closed
for data := range channel {
fmt.Println("RecreateSlice: Data received from channel", data)
stream = append(stream, data)
}
return stream
}
func main() {
result := RecreateSlice()
fmt.Println("MainSlice: ", result)
}

输出:

RecreateSlice: Data received from channel 90
SendFloat64: send data to channel 90
SendFloat64: send data to channel 180
SendFloat64: send data to channel 270
RecreateSlice: Data received from channel 180
RecreateSlice: Data received from channel 270
RecreateSlice: Data received from channel 300
SendFloat64: send data to channel 300
SendFloat64: send data to channel 330
SendFloat64: send data to channel 358
RecreateSlice: Data received from channel 330
RecreateSlice: Data received from channel 358
RecreateSlice: Data received from channel 359
SendFloat64: send data to channel 359
MainSlice:  [90 180 270 300 330 358 359]
  • 注意SendFloat64的订单:
90, 180, 270, 300, 330, 358, 359
  • 注意重新创建切片的顺序:
90, 180, 270, 300, 330, 358, 359

RecreaeSlice返回的切片是有序的(验证(

您可以基于此代码的思想扩展您的解决方案。我试图对代码的某些部分进行注释,以便您能够理解。

最新更新