F#3: Форматирование текста

При работе с любым языком вам, скорее всего, нужно будет отформатировать текст, и F# ничем не отличается.

Поскольку F# является языком .NET, мы всегда можем использовать Console.WriteLine (…) и String.Format (…), где мы можем использовать любой из обычных форматеров, которые вы использовали в своем обычном коде .NET.

Однако F# также поддерживает более похожий на синтаксис метод C, который доступен в модуле Core.Printf. Одна функция внутри него может использоваться вместо использования класса Console.WriteLine (…) .NET.
Эквивалентной функцией F#, которую стоит использовать для записи в стандартный вывод, является printfn, которая на самом деле является предпочтительным методом при работе с форматированием текста в F#.

Почему printfn предпочтительнее Console.WriteLine (…)?


Существует несколько причин, по которым printfn является предпочтительным, некоторые из основных причин приведены ниже:

  • Проверка статического типа. Это означает, что если мы передадим значение int там, где ожидается строка, нас предупредят об этом
  • Поскольку printfn является нативной функцией F#, она действует так же, как любая другая функция F#.

Рассмотрим следующие фрагменты кода

// Некорректный тип
printfn "should be a decimal value %d" "cat"
//Работает
printfn "should be a decimal value %d" 42
// Неверный тип, но работает
Console.WriteLine("should be a decimal value {0}" , "cat")
 
 
// указано неверное количество параметров
printfn "this only expected 1 arg of type decimal %d" 42 "dog"
// указано неверное количество параметров, но работает
Console.WriteLine("this only expected 1 arg of type decimal {0}" , 42, "dog")
// Работает, как ожидалось
printfn "this only expected 2 args of type decimal %d and string %s" 42 "dog"

Если мы сейчас посмотрим на скриншот этого кода в IDE Visual Studio, мы действительно увидим, что строки, которые мы ожидали потерпеть неудачу, ясно показаны как ошибочные:
image

Как использовать printfn?


Возможно, лучше всего начать с рассмотрения некоторых стандартных форматеров, доступных для работы со значениями. В следующей таблицеMSDN показаны стандартные операторы, доступные вам: msdn.microsoft.com/en-us/library/ee370560.aspx

Так что насчет создания отличного форматирования кроме стандартного?


Итак, теперь мы увидели, как записать отформатированный вывод в стандартный вывод (printfn сделал это), но что если мы захотим использовать отформатированную строку в других местах? Что, если мы хотим связать строковое значение с красиво отформатированной строкой, которую мы сконструировали, с использованием некоторых из приведенных выше средств форматирования, или даже хотели записать в StringBuilder или TextWriter, позволяет ли F # сделать это легко?

Ну да, на самом деле это так, вы найдете множество других полезных функций в модуле Core.Printf. Полный список на момент написания этого поста был следующим:

Список

bprintf Печать в StringBuilder.
eprintf Печатает форматированный вывод в stderr.
eprintfn Печатает форматированный вывод в stderr, добавляя новую строку.
failwithf Печатает в строковый буфер и вызывает исключение с заданным результатом. Вспомогательные принтеры должны возвращать строки.
fprintf Печатает на text writter.
fprintfn Печатает в text writter, добавляя новую строку.
kbprintf Аналогично bprintf, но вызывает указанную функцию для генерации результата. Смотрите kprintf.
kfprintf Аналогично fprintf, но вызывает указанную функцию для генерации результата. Смотрите kprintf.
kprintf Как и printf, но вызывает указанную функцию для генерации результата. Например, они позволяют печати принудительно сбрасываться после того, как весь вывод был введен в канал, но не раньше.
kspintf Аналогично sprintf, но вызывает указанную функцию для генерации результата. Смотрите kprintf.
printf Печатает форматированный вывод на стандартный вывод.
printfn Печатает форматированный вывод на стандартный вывод, добавляя новую строку.
sprintf Печатает в строку, используя внутренний строковый буфер, и возвращает результат в виде строки. Вспомогательные принтеры должны возвращать строки.

Я не собираюсь проходить через все это, но я рассмотрю самые распространенные:

bprintf


Печатает в StringBuilder.

let builder = new StringBuilder(524288)
Printf.bprintf builder "This will be a string line : %s\r\n" "cat"
Printf.bprintf builder "This will be a bool line : %b\r\n" true
Printf.bprintf builder "This will be a int line : %u\r\n" 42
Printf.bprintf builder "This will be a hex line : %X\r\n" 255
 
printfn "%s" (builder.ToString())

Это даст этот вывод в консольном приложении F#

fprintf


Печатает в text writer.

use sw = new StreamWriter(@"c:\temp\fprintfFile.txt")
 
fprintf sw "This is a string line %s\r\n" "cat"
fprintf sw "This is a int line %i" 10
 
sw.Close()


Это приведет к тому, что файл будет создан в temp
image

sprintf

let result = Printf.sprintf "This will return a formatted string : %s\r\n" "cat"
printfn "%s" result

image

© Habrahabr.ru