Golang - 按扇形排序
Golang - Sorting on fan in
我正在随机生成一堆日志消息,生成后,我需要在将它们写入日志之前按时间戳对它们进行排序。我正在利用 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)
为什么我无法从频道收到值?
我认为错误消息是不言自明的。看看这个:
for i := range ch {
logs.Messages = append(logs.Messages, <- i)
}
ch
是 chan <- *CommonLogFormat
类型。 ch
是一个频道。通道上的 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
最后一行适用于在通道上测距的情况,第一个迭代值是元素。
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.
我正在随机生成一堆日志消息,生成后,我需要在将它们写入日志之前按时间戳对它们进行排序。我正在利用 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)
为什么我无法从频道收到值?
我认为错误消息是不言自明的。看看这个:
for i := range ch {
logs.Messages = append(logs.Messages, <- i)
}
ch
是 chan <- *CommonLogFormat
类型。 ch
是一个频道。通道上的 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
最后一行适用于在通道上测距的情况,第一个迭代值是元素。
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.