Интерфейс:
type WriterTo interface {
WriteTo(w io.Writer) (n int64, err error)
}Суть: тип сам берёт управление на себя и решает, как именно записать свои данные в переданный
Writer.Зачем это нужно
io.Copy по умолчанию работает через буфер 32KB и читает кусок из источника, пишет в назначение, и так по кругу. Данные гоняются через userspace.
Но некоторые типы знают более эффективный путь. Например,
*os.File на Linux может использовать системный вызов sendfile и данные перемещаются на уровне ядра, без копирования в память процесса.Как io.Copy это использует
Перед тем как запустить свой буферный цикл, она проверяет интерфейсы:
// 1. Источник умеет писать сам?
if wt, ok := src.(WriterTo); ok {
return wt.WriteTo(dst)
}
// 2. Назначение умеет читать само?
if rf, ok := dst.(ReaderFrom); ok {
return rf.ReadFrom(src)
}
// 3. Fallback — буфер 32KB
Если источник реализует
WriterTo, то io.Copy просто уступает ему управление.🐸 Библиотека Go для собеса