登录
首页 >  Golang >  Go问答

Golang 中的通道

来源:stackoverflow

时间:2024-03-09 21:36:26 421浏览 收藏

大家好,我们又见面了啊~本文《Golang 中的通道》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~

问题内容

我正在尝试实现一个函数,该函数使用通道向另一个函数发送不确定数量的变量(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
  • 注意 recreateslice 的顺序:
90, 180, 270, 300, 330, 358, 359

并且recreateslice返回的切片是有序的(验证)

您可以根据此代码的思想扩展您的解决方案。我尝试对部分代码进行注释以便您能够理解。

今天关于《Golang 中的通道》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>