Функция io.NopCloser

Функция io.NopCloser принимает в качестве параметра интерфейс io.Reader и возвращает интерфейс io.ReadCloser, у которого метод Close всегда возвращает nil. Это полезно в тех случаях, когда требуется передать читателя в функцию, ожидающую io.ReadCloser, но при этом нет необходимости выполнять какие-либо действия по закрытию ресурса. Например, при работе с данными из памяти или тестировании.

Синтаксис

gofunc NopCloser(r io.Reader) io.ReadCloser

Пример

Давайте создадим читателя из строки с помощью strings.NewReader и передадим его в io.NopCloser:

gopackage main

import (
  "fmt"
  "io"
  "strings"
)

func main() {
  r := strings.NewReader("hello world")
  rc := io.NopCloser(r)

  data, err := io.ReadAll(rc)
  if err != nil {
    fmt.Println("Error:", err)
    return
  }

  fmt.Println(string(data))

  // Закрываем - метод ничего не делает
  err = rc.Close()
  fmt.Println("Close error:", err)
}

Результат выполнения кода:

go"hello world"
"Close error: <nil>"

Пример

Давайте используем io.NopCloser в функции, которая ожидает io.ReadCloser и всегда вызывает Close:

gopackage main

import (
  "fmt"
  "io"
  "strings"
)

func processReader(rc io.ReadCloser) error {
  defer rc.Close()

  data, err := io.ReadAll(rc)
  if err != nil {
    return err
  }

  fmt.Println(string(data))
  return nil
}

func main() {
  r := strings.NewReader("test data")
  rc := io.NopCloser(r)

  err := processReader(rc)
  if err != nil {
    fmt.Println("Error:", err)
  }
}

Результат выполнения кода:

go"test data"

Пример

Давайте сравним поведение обычного файла и io.NopCloser:

gopackage main

import (
  "fmt"
  "io"
  "os"
  "strings"
)

func main() {
  // Обычный файл
  file, err := os.Open("test.txt")
  if err != nil {
    fmt.Println("Error:", err)
    return
  }
  defer file.Close()
  fmt.Println("File:", file)

  // NopCloser
  r := strings.NewReader("hello")
  rc := io.NopCloser(r)
  err = rc.Close()
  fmt.Println("NopCloser close error:", err)
}

Результат выполнения кода:

go"File: &{0xc0000a0000}"
"NopCloser close error: <nil>"

Смотрите также

  • функцию io.ReadAll,
    которая читает все данные из читателя
  • функцию io.LimitReader,
    которая ограничивает количество читаемых данных
  • функцию io.MultiReader,
    которая объединяет несколько читателей в один
  • функцию io.Copy,
    которая копирует данные из читателя в писатель