【问题标题】:Golang - Sorting on fan inGolang - 按风扇排序
【发布时间】:2017-04-19 04:25:22
【问题描述】:

我正在随机生成一堆日志消息,在它们生成之后,我需要在将它们写入日志之前按时间戳对它们进行排序。我正在使用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)

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

【问题讨论】:

    标签: sorting for-loop go concurrency channel


    【解决方案1】:

    我认为错误消息是不言自明的。看看这个:

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

    ch 的类型为 chan &lt;- *CommonLogFormatch 是一个频道。通道上的for range 循环产生在通道上发送的值,这些值将存储在循环变量i 中。 i 不是通道,而是通道上发送的值,因此它将是 *CommonLogFormat 类型。

    所以没有必要,而且你实际上无法从它那里接收,它已经是你想要从它那里接收到的东西了。只需附加i:

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

    Spec: For statements 详细说明了循环变量在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
    

    最后一行适用于在通道上测距的情况,第一个迭代值是元素。

    对于通道,生成的迭代值是通道上发送的连续值,直到通道为closed。如果频道是nil,则范围表达式永远阻塞。

    【讨论】:

    • 啊,好吧。这实际上很有意义,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2013-06-14
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多