2015 подписчиков
👣 Существует ли аналог std::endl и std::flush в Go?
⏩Итак, мы все знаем, что в большинстве пользовательских современных ОС стандартный ввод и вывод работает через буфер. Чтобы буфер скинуть в C++ есть std::flush и std::endl, который ещё и переносит на новую строку. Есть ли такое в Go?
⏩Если коротко, то нет, не существует.
Практически все операции вывода в Go используют интерфейсы io.Writer или io.WriteCloser. В этих интерфейсах есть только метод Write. Эти интерфейсы радикально проще стандартного std::basic_stream. Метод Flush или аналоги в io.Writer отсутствуют.
Теперь об объектах std::cin и std::cout. В Go им соответствуют os.Stdin и os.Stdout. Переменная os.Stdout — это указатель на объект типа os.File.
В Go вывод в файлы не буферизуется, метод File.Write пишет напрямую в файловый дескриптор через системный вызов pwrite. Соответственно, в типе File нет метода, аналогичного std::Flush. Есть метод Sync, который вызывает системный вызов fsync для открытого файлового дескриптора, но это не то. Этот системный вызов заставляет ядро сбросить на диск буферы, отведённые под файловый дескриптор.
Из-за того, что File пишет напрямую в файл, функции fmt.Print и fmt.Println, а так же методы File.WriteString и File.Write, очень медленные. На больших объемах вывода они медленнее буферизованного вывода раз в 100.
Буферизованный ввод-вывод предоставляет пакет bufio. В пакете определён тип bufio.Writer, в котором есть метод Flush. Этот тип в десятки раз ускоряет вывод, но, к сожалению, нет типа для буферизованного файла: нельзя написать os.Stdout = bufio.NewWriter(os.Stdout). Поэтому если вам нужен быстрый аналог fmt.Print, то нужно пользоваться fmt.Fprint и явно указывать writer:
Stdout_Buffered := bufio.NewWriter(os.Stdout)
...
fmt.Fprintln(Stdout_Buffered, "Hello, world!")
...
Stdout_Buffered.Flush()
Аналога для std::endl в стандартных пакетах Go нет.
Функция fmt.Fprintln пишет в объект io.Writer системно-зависимый конец строки, но, поскольку io.Writer не содержит никаких аналогов flush, нижележащий буфер (если есть) эта функция не синхронизует.
1 минута
31 марта 2024