Найти в Дзене
Wissance

Собираем строки/текст в Go лучше чем c fmt

Оглавление
Форматирование текста в Go в стиле аналогичном языкам C# и Python, но еще быстрее чем fmt.Sprintf !
Форматирование текста в Go в стиле аналогичном языкам C# и Python, но еще быстрее чем fmt.Sprintf !

Что такое сборка текста и почему лучше чем fmt?

Сборка текста это подготовка текста на основе шаблона и дополнительных данных, такая подготовка часто используется, например, в следующих случаях:

  • задание строк подключения, например к БД;
  • формировании кода SQL-запросов и описание операций с данными;
  • формирование текста электронных писем, сообщений, уведомлений;
  • формировании единого детализированного описания ошибок (лог ошибок).

Теперь когда понятно что подразумевается под форматированием текста, зададимся вопросом, а что значит лучше? По лучше мы рассматриваем 2 критерия:

  1. Более простое использование функций форматирования
  2. Более высокая производительность кода

В языке программирования Go в пакете fmt существует функция fmt.Sprintf для форматирования текста. Если мы взгляним на язык С++ идейным наследником, которого является Go, то функция sprintf была и в стандартной библиотеке С, и при расширении возможностей языка С++ появилась возможность использования стримов (stringstream) и дополнительные опции форматирования при использовании потоков ввода-вывода через std:setw. При рассмотрении других языков, например C# и Python мы имеем функции string.Format, в которых используется {N} для задания номер аргумента. Мы в Висанс часто используем C# и Python в наших проектах (C# хорош как для десктопных приложений, так для серверных и системного ПО), а Python идеально подходит для какого-то быстрого прототипирования и автоматизации. Поэтому возвращаясь к форматированию мы решили создать библиотеку, которая навела бы мост между C#, Python и Go через создание функций Format. Ранее мы писали об этой библиотеке в нашей статье тут. Кроме создания некоторой преемственности согласно испытаниям методы Format и FormatComplex оказались быстрее чем fmt.Sprintf, для этого были написаны benchmark-тесты и получены результаты. Иногда производительность при обработке большого текста может стать критически важной, поэтому данный результат нам кажется очень хорошим. Чем хорош fmt.Sprintf так это тем, что можно тонко настраивать формат вывода того или иного аргумента. До версии 1.2.0. wissance/stringFormatter (далее sf) этой возможности НЕ было, но начиная с 1.2.0 мы можем также тонко настраивать формат аргументов.

Возможности форматирования sf 1.2.0+

Чем вообще хорош вариант c функциями Format смотри в нашей предыдущей статье, а мы вкратце расскажем как использовать задание форматирования отдельных аргументов в sf.

  1. Задание двоичного формата вывода чисел: {0:B}, при этом если мы передадим на вход, например, число 15, то вывод будет -> 1111, а если уточним количество разрядов выодимого числа, например, 8 - {0:B8}, то это же число 15 будет выведено как -> 00001111.
  2. Часто программисты имеют дело с шестнадцатиричным (hex) форматом чисел, для вывода чисел в этом формате необходимо указать X - {0:X}, если на вход подадим число 250, то оно будет выведено как fa, аналогично с бинарным форматом мы можем задать количество разрядов, например,
    {0:X4} тогда это же число 250 будет выведено как 00fa.
  3. Мы можем выводить числа и в восьмеричном формате используя o - {0:o} при этом при подаче числа 11 будет выведено 14.
  4. С целочисленными у нас все понятно и возможности вывода целых чисел аналогичны возможностям fmt, а что же для чисел с плавающей точкой ? Для вывода чисел с плавающей точкой в научном формате используем модификатор E, например {0:E2} с числом 191.0478 выведет 1.91e+02, где е+02 эквивалентно 10 в степени 2, т.е. 100. Дополнительно есть модификатор F, который позволяет выводить числа с плавающей точкой без приведения их к научному формату:
  • {0:F} с числом 10.4567890 выведет 10.456789
  • {0:F4} с числом 10.4567890 выведет 10.4568 (обрежет без округления)
  • {0:F8} с все тем же числом 10.4567890 выведет 10.45678900
    В целом вывод чисел с плавающей точкой по возможностям эквивалентен

5. Дополнительно была добавлена маленькая, но полезная фича с выводом аргумента в процентах от какого-то значения, используя модификатор формата P, например {0:P100}, означает % от числа 100, при передаче в качестве аргумента числа 12 мы получим вывод - 12% .

У sf есть два метода для форматирования текста - Format и FormatComplex, последний позволяет использовать словарь в виде пар ключ=значение и подставлять значение из этого словаря по ключу и этот метод также позволяет задавать формат аргумента. Рассмотрим минимальный пример с выводом данных от метеостанции:

sf.FormatComplex("Today temperature is {temp:F4}, humidity is {hum:P100}", map[string]any {"temp":12.3456, "hum":60})

Что приведет к формированию строки: "Today temperature is 12.3456, humidity is 60%" . Более полный набор примеров использования приведен в тестах функций Format и FormatComplex данного проекта. Дорогой читатель, если тебя не затруднит оценить наш труд в виде звезды нашей библиотеке на Github (https://github.com/Wissance/stringFormatter), то будем благодарны и признательны, контрибьютинг также приветствуется.

Заключение

Несмотря на то, что форматирование текста это стандартная возможность многих SDK и вообще основа всего, но, тем не менее, создание альтернативных решений и библиотек аналогичных библиотекам в других языках является полезной задачей, которая помогает лечге начать использовать язык Go в проектах. Спасибо, что дочитали, успехов в проектировании и написании программного обеспечения с использованием языка Go.