I'd like some way to split long single-ling String...
# language-evolution
r
I'd like some way to split long single-ling Strings in my source file, but have the compiled code be a single String. As I understand it, the options to split a long String like this now are all lacking in one or more ways, meaning that in practice these long Strings just remain long Strings in the source, despite exceeding max line length lint rules: • use a
buildString
block: overkill for this scenario, and while performant, still some runtime overhead • String concatenation: not visually appealing, runtime overhead • some combination of raw strings with
trimMargin
and removing newlines: runtime overhead Thoughts?
1
f
Where do you get the runtime hit info from for concat?
r
I believe string concat on Kotlin uses
StringBuilder
internally.
My information could be out-of-date though
At least on JVM, no idea about other platforms
Ok, checked the bytecode, at least for JVM, and see the following: • If concat multiple constant strings, then Kotlin adds them into the bytecode as a single constant • If any part of the expression is non-constant (including templates), then the code is compiled into a
StringBuilder
. • Mixing concat with templates does not create any extra nested
StringBuilder
Given that, concat should be safe to use with no additional overhead. Nice!
e
also
-Xstring-concat=indy-with-constants
will be default when targeting Java 9+
r
y
Also, AFAIK trimMargin is performed at compile time, not runtime, so in fact it should be just as performant
f
Correct,
trimIndent
and
trimMargin
(KT-43861). 🙂
y
Yep, and the most reliable source of all, The Wharton (and KT-22505 as well)
e
unfortunately, even if they are evaluated at compile time, they are not compile-time constants so they can't be used for
const val
or annotations; see https://youtrack.jetbrains.com/issue/KT-14652
f
That's when the good old
+
comes back into the picture.
e
Would love if Kotlin had what Ruby has for this:
Copy code
long_str = "pretend this is a " \
  "very long string"
puts long_str # "pretend this is a very long string"
f
But that's exactly what
+
does?!?
Copy code
const val longString = "pretend this is a " +
    "very long string"
// GENCODE:
// public static final String longString = "pretend this is a very long string";
e
why?
+
works just fine, and it only works like that in Ruby due to implicit string literal concatenation, which is a misfeature in Ruby and Python leading to
Copy code
"foo" "bar" == "foobar"
👍 1
e
@Fleshgrinder nice, didn't know generated code was optimized