sorting - Golang - 按扇形排序

标签 sorting for-loop go concurrency channel

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

但是,当我去接收来自 channel 的日志消息时,我得到这个错误:

invalid operation: <-i (receive from non-chan type *CommonLogFormat)

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

最佳答案

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

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

ch类型为 chan <- *CommonLogFormat . ch是一个 channel 。 for range在 channel 上循环产生在 channel 上发送的值,这些值将存储在循环变量 i 中. i不是 channel ,而是在 channel 上发送的值,因此它将是 *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

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

For channels, the iteration values produced are the successive values sent on the channel until the channel is closed. If the channel is nil, the range expression blocks forever.

关于sorting - Golang - 按扇形排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40963042/

相关文章:

windows - `forfiles`在什么时候枚举了一个目录(树)?

python - 检查 QuerySet 中是否存在对象

json - 将 JSON 解码为结构,同时支持属性值的不同类型

go - 使用 base64.StdEncoding.DecodeString(str) 时输入字节 4 处的非法 base64 数据

go mod vendor 返回 "all matched no packages"

mysql - 重新排序MySQL中表的显示顺序

java - 按字母顺序对 JSONArray 进行排序(单值)

javascript - 按另一个数组的顺序对数组进行排序

php - 使用 array_multisort 对整数进行升序排序并相应地对相应的字符串进行排序(php)

Java在for循环外声明迭代器