Golang - 对fan in进行排序

3

我正在随机生成一堆日志消息,在它们生成后,我需要按时间戳对它们进行排序,然后再写入日志。我正在利用sort库的sort.Interface方面,以便根据我的时间戳进行排序。我正在使用一个扇入并发设计,因此我的排序函数聚合了所有goroutine的日志消息,然后对它们进行排序。

这是我的代码:

type CommonLogFormat struct {
    HostIP         string
    UserIdent      string
    User           string
    Timestamp      string
    Request        string
    HttpStatusCode int
    Size           int
}

type Logs struct {
    Messages []*CommonLogFormat
}

func sortByTimestamp(ch chan <- *CommonLogFormat) *Logs {
    logs := &Logs{Messages: make([]*CommonLogFormat, 1)}

    for i := range ch {
        logs.Messages = append(logs.Messages, <- i)
    }

    sort.Sort(logs)

    return logs
}

func (l Logs) Len() int {
    return len(l.Messages)
}

func (l Logs) Less(i,j int) bool {
    return l.Messages[i].Timestamp < l.Messages[j].Timestamp
}

func (l *Logs) Swap(i,j int) {
    l.Messages[i], l.Messages[j] = l.Messages[j], l.Messages[i]
}

然而,当我从通道接收日志消息时,出现以下错误:
invalid operation: <-i (receive from non-chan type *CommonLogFormat)

为什么我无法从通道接收值?

1个回答

2
我认为错误信息已经很清楚地说明了问题。看看这个:

我觉得错误消息已经非常自我解释了。看看这个:

for i := range ch {
    logs.Messages = append(logs.Messages, <- i)
}

ch 是类型为 chan <- *CommonLogFormat 的通道。它是一个通道。使用 for range 循环遍历通道,可以获取通道中发送的值,这些值将存储在循环变量 i 中。 i 不是通道,而是通道中发送的值,因此它的类型是 *CommonLogFormat

因此,没有必要从中接收,实际上也无法接收,因为它已经是您想要从中接收的内容。只需将 i 添加到末尾即可:

for i := range ch {
    logs.Messages = append(logs.Messages, i)
}

规范:For语句 中详细说明了在for range的情况下循环变量是什么:

Range expression                          1st value          2nd value

array or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E
string          s  string type            index    i  int    see below  rune
map             m  map[K]V                key      k  K      m[k]       V
channel         c  chan E, <-chan E       element  e  E

最后一行适用于通道遍历,第一个迭代值是元素本身。

对于通道,产生的迭代值是在通道上发送的连续值,直到该通道被关闭。如果通道为nil,则范围表达式将永久阻塞。


啊,好的。那真的很有道理,谢谢! - SiennaD.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接