what's the best way to hardcode a multiple-line string?
Solution 1
I think there is no problem with using StringBuilder
in F# as you did.
There is a function fprintfn
in Printf module, so you can use it with a StringWriter
object:
let sw = new StringWriter()
fprintfn sw "myline1"
fprintfn sw "myline2"
fprintfn sw "myline3"
sw.ToString()
I like fprintf
and fprintfn
since they are flexible. You can write to console output by supplying stdout
instead.
Solution 2
Little known feature: you can indeed indent string content - by ending each line with a backslash. Leading spaces on the following line are stripped:
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"
You will still need to include \n
or \n\r
at line ends though (as done in the example above), if you want these embedded in your final string.
Edit to answer @MiloDCs question:
To use with 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"
Solution 3
If you are under F# 3.0, triple-quoted strings may be the answer:
let x = """
myline1
myline2
myline3"""
Solution 4
I'm surprised nobody has mentioned this:
[ "My first line"
"second line"
"another line" ]
|> String.concat "\n"
Solution 5
You can create directly multi-line string literals in F#:
let multiLineStr =
"myline1
myline2
myline3"
and C#:
var multiLineStr =
@"myline1
myline2
myline3";
colinfang
Updated on June 02, 2022Comments
-
colinfang almost 2 years
In unit test I would like to hard code a block of lines as a string.
In C# I would do
var sb = new StringBuilder(); sb.AppendLine("myline1"); sb.AppendLine("myline2"); sb.AppendLine("myline3");
Since I converted to F# I tried to minimize the usage of .Net method by using
bprintf
instead, but somehow there is nobprintfn
support which seems strange to me.It is tedious to add
\r\n
at the end of each line manually.Or is there any better way than
StringBuilder
? -
MiMo over 11 yearsI think this gives
myline1myline2myline3
- without the end lines -
colinfang over 11 yearsOne drawback of this is, that you cannot indent the string content which looks bad.
-
Thorkil Holm-Jacobsen over 11 yearsWow, did NOT know that! +1
-
Onorio Catenacci over 11 yearsGood tip @Kit--that's a new one to me too.
-
colinfang over 11 yearsit is basically the same as @jellyfish 's method, but looks extremely useful under such formatting.
-
knocte about 10 yearsI don't like this approach because I guess it wouldn't use the platform-agnostic
Environment.NewLine
-
Michelrandahl over 7 yearsthis is IMO how triple quotes should have worked. If you want to write pretty code with triple quotes as it is now it just screws up the indentation.
-
MiloDC almost 4 yearsHow to do this with sprintf?
-
Kit almost 4 years@MiloDC Edited to answer your question. ;-)
-
Aisah Hamzah almost 4 yearsThe
@
prefix can also be used in F#. -
Pac0 over 3 yearsWith sprintf, I get an error when using formatters.
sprintf "foo %s bar,\n\
then on the other line:foobar %s\n." "a" "b"
(with indentation) is getting meexpecting a string -> a -> b but given a string -> string
. EDIT : wait, it compiles and work fine! The error is only in Visual Studio editor! Looks like a VS bug. -
Pac0 over 3 yearscaveat with that approach is that you must "clip" the string lines at the beginning of line, otherwise the indentation spaces will be taken into the string. It looks a bit ugly when you have indented code,