как лучше всего жестко закодировать многострочную строку?

В модульном тесте я хотел бы жестко закодировать блок строк в виде строки.

В С# я бы сделал

var sb = new StringBuilder();
sb.AppendLine("myline1");
sb.AppendLine("myline2");
sb.AppendLine("myline3");

Поскольку я перешел на F #, я попытался свести к минимуму использование метода .Net, используя вместо этого bprintf, но почему-то нет поддержки bprintfn, что мне кажется странным.

Утомительно добавлять \r\n в конце каждой строки вручную.

Или есть способ лучше, чем StringBuilder?


person colinfang    schedule 29.01.2013    source источник
comment
В настоящее время в C# мы бы использовали @"" :)   -  person aloisdg    schedule 17.10.2018


Ответы (7)


Я думаю, что нет проблем с использованием StringBuilder в F#, как это сделали вы.

В модуле Printf есть функция fprintfn, поэтому вы можете использовать ее с объект StringWriter:

let sw = new StringWriter()
fprintfn sw "myline1"
fprintfn sw "myline2"
fprintfn sw "myline3"
sw.ToString()

Мне нравятся fprintf и fprintfn, так как они гибкие. Вы можете записать вывод консоли, указав вместо этого stdout.

person pad    schedule 29.01.2013

Малоизвестная функция: вы действительно можете отступать от строкового содержимого, заканчивая каждую строку обратной косой чертой. Начальные пробелы в следующей строке удаляются:

let poem = "The lesser world was daubed\n\
            By a colorist of modest skill\n\
            A master limned you in the finest inks\n\
            And with a fresh-cut quill.\n"

Вам все равно нужно будет включить \n или \n\r в конце строки (как это сделано в приведенном выше примере), если вы хотите, чтобы они были встроены в вашу окончательную строку.

Изменить, чтобы ответить на вопрос @MiloDCs:

Для использования с sprintf:

let buildPoem character =
    sprintf "The lesser world was daubed\n\
             By a colorist of modest skill\n\
             A master limned %s in the finest inks\n\
             And with a fresh-cut quill.\n" character

buildPoem "you"            
buildPoem "her"
buildPoem "him"
person Kit    schedule 30.01.2013
comment
Вау, НЕ знал! +1 - person Thorkil Holm-Jacobsen; 30.01.2013
comment
Хороший совет @Kit - для меня он тоже новый. - person Onorio Catenacci; 31.01.2013
comment
Мне не нравится этот подход, потому что я предполагаю, что он не будет использовать платформенно-независимую Environment.NewLine - person knocte; 17.04.2014
comment
Как это сделать с помощью sprintf? - person MiloDC; 16.07.2020
comment
@MiloDC Отредактировано, чтобы ответить на ваш вопрос. ;-) - person Kit; 17.07.2020
comment
С sprintf я получаю сообщение об ошибке при использовании средств форматирования. sprintf "foo %s bar,\n\ , затем в другой строке: foobar %s\n." "a" "b" (с отступом) получает меня expecting a string -> a -> b but given a string -> string. РЕДАКТИРОВАТЬ: подождите, он компилируется и работает нормально! Ошибка только в редакторе Visual Studio! Похоже на баг VS. - person Pac0; 05.11.2020

Если вы используете F# 3.0, строки в тройных кавычках могут быть ответом:

let x = """
myline1
myline2
myline3"""   
person bytebuster    schedule 29.01.2013
comment
предостережение при таком подходе заключается в том, что вы должны обрезать строки строки в начале строки, иначе пробелы отступа будут взяты в строку. Это выглядит немного некрасиво, когда у вас есть отступ в коде, - person Pac0; 05.11.2020

Я удивлен, что никто не упомянул это:

[ "My first line"
  "second line"
  "another line" ]
|> String.concat "\n"
person J D    schedule 31.01.2013
comment
это в основном то же самое, что и метод @jellyfish, но выглядит чрезвычайно полезным при таком форматировании. - person colinfang; 01.02.2013
comment
это ИМО, как должны были работать тройные кавычки. Если вы хотите написать красивый код с тройными кавычками, как сейчас, это просто испортит отступ. - person Michelrandahl; 05.08.2016

Вы можете напрямую создавать многострочные строковые литералы в F#:

let multiLineStr = 
  "myline1
myline2
myline3"

и С#:

var multiLineStr =
  @"myline1
myline2
myline3";
person MiMo    schedule 29.01.2013
comment
Одним из недостатков этого является то, что вы не можете сделать отступ для содержимого строки, что выглядит плохо. - person colinfang; 29.01.2013
comment
Префикс @ также можно использовать в F#. - person Abel; 17.07.2020

Вы можете определить свою собственную функцию bprintfn:

let bprintfn bldr fmt =
  (bldr, fmt) ||> Printf.kbprintf bldr.AppendLine

Или, чтобы определить многострочный литерал, вы можете использовать тройные кавычки, как предлагает bytebuster, или «дословный литерал», который начинается с @ (см. Строки в MSDN).

person Daniel    schedule 29.01.2013
comment
Я думаю, что это дает myline1myline2myline3 - без конечных строк - person MiMo; 29.01.2013

Я не знаком с F#, но вы могли бы адаптировать мой обычный подход:

['line1', 'line2', 'line3'].join('\n'); //javascript

StringUtils.join(Arrays.asList("line1", "line2", "line3"), "\n")); // java, using Apache Commons Lang
person craigsnyders    schedule 29.01.2013