切片边界超出范围
Slice bounds out of range
以下代码引发 slice bounds out of range
错误。
func main() {
file, err := os.Open("mails.mbox")
if err != nil {
log.Fatal(err)
}
defer file.Close()
m := mbox.NewReader(file) // bufio.NewScanner(file)
for {
data, err := m.NextMessage() // .Scan()
if err == io.EOF {
break
} else if err != nil {
log.Fatalf("Unexpected error after NextMessage(): %v", err)
}
go saveMessage(data)
}
// By now we should not have any messages inside.
if _, err := m.NextMessage(); err != io.EOF {
log.Fatalf("We still have data: %v", err)
}
}
func saveMessage(data io.Reader) {
msg, err := mail.ReadMessage(data)
if err != nil {
return
}
// insert msg into database
}
我想同时处理 saveMessage
函数。
一次 100 个或基于可用内存。
从 NextMessage 返回的 mbox reader 和消息 reader 对于并发访问不安全。由于 mbox 实现中的数据争用,程序出现混乱。
通过在启动 goroutine 之前收集消息数据来修复:
for {
data, err := m.NextMessage() // .Scan()
if err == io.EOF {
break
} else if err != nil {
log.Fatalf("Unexpected error after NextMessage(): %v", err)
}
msg, err := mail.ReadMessage(data)
if err != nil {
log.Fatal(err)
}
go saveMessage(msg)
}
...
func saveMessage(msg *mail.Message) {
// insert msg into database
}
以下代码引发 slice bounds out of range
错误。
func main() {
file, err := os.Open("mails.mbox")
if err != nil {
log.Fatal(err)
}
defer file.Close()
m := mbox.NewReader(file) // bufio.NewScanner(file)
for {
data, err := m.NextMessage() // .Scan()
if err == io.EOF {
break
} else if err != nil {
log.Fatalf("Unexpected error after NextMessage(): %v", err)
}
go saveMessage(data)
}
// By now we should not have any messages inside.
if _, err := m.NextMessage(); err != io.EOF {
log.Fatalf("We still have data: %v", err)
}
}
func saveMessage(data io.Reader) {
msg, err := mail.ReadMessage(data)
if err != nil {
return
}
// insert msg into database
}
我想同时处理 saveMessage
函数。
一次 100 个或基于可用内存。
从 NextMessage 返回的 mbox reader 和消息 reader 对于并发访问不安全。由于 mbox 实现中的数据争用,程序出现混乱。
通过在启动 goroutine 之前收集消息数据来修复:
for {
data, err := m.NextMessage() // .Scan()
if err == io.EOF {
break
} else if err != nil {
log.Fatalf("Unexpected error after NextMessage(): %v", err)
}
msg, err := mail.ReadMessage(data)
if err != nil {
log.Fatal(err)
}
go saveMessage(msg)
}
...
func saveMessage(msg *mail.Message) {
// insert msg into database
}