Ошибка bufio.ErrNegativeAdvance
Ошибка bufio.ErrNegativeAdvance возникает при работе с буферизированным вводом-выводом,
когда функция чтения пытается выполнить операцию с отрицательным смещением.
Эта ошибка является константой, определенной в пакете bufio,
и возвращается в случаях, когда количество прочитанных байт оказывается отрицательным.
Обычно ошибка bufio.ErrNegativeAdvance появляется при использовании
собственных функций разбиения (split functions) для bufio.Scanner,
когда функция возвращает отрицательное значение смещения.
Также она может возникнуть при некорректной работе с Reader,
когда метод возвращает отрицательное количество прочитанных байт.
Синтаксис
var ErrNegativeAdvance = errors.New("bufio: negative advance")
Ошибка возвращается в случаях, когда продвижение по данным должно быть положительным или нулевым, но получается отрицательное значение.
Пример возникновения ошибки
Рассмотрим пример, где ошибка возникает при создании собственной функции разбиения:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "hello world"
scanner := bufio.NewScanner(strings.NewReader(data))
scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
// Возвращаем отрицательное смещение
return -1, nil, nil
})
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
}
Результат выполнения кода:
"bufio: negative advance"
В этом примере ошибка возникает потому, что функция разбиения возвращает отрицательное значение смещения (-1), что недопустимо.
Правильная реализация функции разбиения
Чтобы избежать ошибки, функция разбиения должна всегда возвращать неотрицательное смещение. Обычно это длина токена или 0, если токен не найден:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "hello world"
scanner := bufio.NewScanner(strings.NewReader(data))
scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
// Правильное смещение
if len(data) == 0 {
return 0, nil, nil
}
return len(data), data, nil
})
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
}
Результат выполнения кода:
"hello world"
В этом примере функция разбиения возвращает положительное смещение, равное длине данных, что позволяет корректно обработать ввод.
Обработка ошибки
При работе со Scanner ошибку следует проверять после завершения цикла:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "test input"
scanner := bufio.NewScanner(strings.NewReader(data))
scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
// Некорректное смещение
return -5, nil, nil
})
for scanner.Scan() {
fmt.Println(scanner.Text())
}
err := scanner.Err()
if err == bufio.ErrNegativeAdvance {
fmt.Println("Negative advance error:", err)
} else if err != nil {
fmt.Println("Other error:", err)
}
}
Результат выполнения кода:
"Negative advance error: bufio: negative advance"
Важно проверять ошибку после цикла сканирования, чтобы корректно
обработать возможные проблемы, включая ErrNegativeAdvance.
Смотрите также
-
ошибку
bufio.ErrTooLong,
возникающую при слишком длинном токене -
ошибку
bufio.ErrAdvanceTooFar,
возникающую при слишком большом смещении -
ошибку
bufio.ErrBadReadCount,
возникающую при некорректном количестве прочитанных байт -
ошибку
bufio.ErrInvalidUnreadByte,
возникающую при некорректном откате байта