Тип strings.Reader

Тип strings.Reader реализует интерфейс io.Reader для чтения данных из строки. Он позволяет читать данные из строки по частям, что полезно при работе с большими строками или при необходимости использования строк в качестве источника данных для функций, ожидающих io.Reader. В отличие от простого преобразования строки в срез байтов, strings.Reader предоставляет эффективное чтение без копирования данных.

Создание strings.Reader

Для создания strings.Reader используется функция strings.NewReader, которая принимает строку и возвращает указатель на strings.Reader:

gopackage main

import (
  "fmt"
  "strings"
)

func main() {
  reader := strings.NewReader("Hello, World!")
  fmt.Printf("Type: %T\n", reader)
}

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

goType: *strings.Reader

Основные методы

Тип strings.Reader предоставляет методы для чтения данных: Read читает данные в срез байтов, ReadByte читает один байт, ReadRune читает один символ rune, а ReadString читает данные до указанного разделителя.

Пример использования Read

Метод Read читает данные из строки в срез байтов и возвращает количество прочитанных байтов. Давайте прочитаем данные из строки по частям:

gopackage main

import (
  "fmt"
  "strings"
)

func main() {
  reader := strings.NewReader("abcde")
  buf := make([]byte, 3)

  n, err := reader.Read(buf)
  if err != nil {
    fmt.Println("Error:", err)
    return
  }

  fmt.Printf("Read %d bytes: %s\n", n, buf[:n])
}

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

go"Read 3 bytes: abc"

Пример использования ReadByte

Метод ReadByte читает один байт из строки и возвращает его. Давайте прочитаем все байты из строки по одному:

gopackage main

import (
  "fmt"
  "strings"
)

func main() {
  reader := strings.NewReader("abcde")

  for {
    b, err := reader.ReadByte()
    if err != nil {
      break
    }
    fmt.Printf("%c ", b)
  }
  fmt.Println()
}

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

go"a b c d e "

Пример использования ReadRune

Метод ReadRune читает один символ rune из строки, возвращая символ и его размер в байтах. Это особенно полезно для строк с многобайтовыми символами:

gopackage main

import (
  "fmt"
  "strings"
)

func main() {
  reader := strings.NewReader("Привет")

  for {
    r, size, err := reader.ReadRune()
    if err != nil {
      break
    }
    fmt.Printf("Rune: %c, Size: %d bytes\n", r, size)
  }
}

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

go"Rune: П, Size: 2 bytes\nRune: р, Size: 2 bytes\nRune: и, Size: 2 bytes\nRune: в, Size: 2 bytes\nRune: е, Size: 2 bytes\nRune: т, Size: 2 bytes"

Пример использования ReadString

Метод ReadString читает данные до первого вхождения указанного байта-разделителя. Давайте прочитаем строку до запятой:

gopackage main

import (
  "fmt"
  "strings"
)

func main() {
  reader := strings.NewReader("first,second,third")

  str, err := reader.ReadString(',')
  if err != nil {
    fmt.Println("Error:", err)
    return
  }

  fmt.Printf("Read: %s", str)
}

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

go"Read: first,"

Управление позицией чтения

Тип strings.Reader позволяет управлять позицией чтения с помощью методов Seek и Reset. Метод Seek устанавливает позицию чтения, а Reset сбрасывает позицию в начало.

gopackage main

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

func main() {
  reader := strings.NewReader("abcdefghij")

  // Сдвигаем позицию на 3 байта от начала
  reader.Seek(3, io.SeekStart)

  buf := make([]byte, 3)
  reader.Read(buf)
  fmt.Printf("After seek: %s\n", buf[:3])

  // Сбрасываем позицию в начало
  reader.Reset("abcdefghij")
  reader.Read(buf)
  fmt.Printf("After reset: %s\n", buf[:3])
}

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

go"After seek: def\nAfter reset: abc"

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

  • функцию strings.NewReader,
    которая создает новый strings.Reader из строки
  • тип bytes.Reader,
    который предоставляет аналогичный функционал для срезов байтов
  • тип strings.Builder,
    который используется для эффективного построения строк
  • тип bytes.Buffer,
    который предоставляет буферизованное чтение и запись байтов