Is there a way of delaying evaluation of string te...
# announcements
p
Is there a way of delaying evaluation of string templates ? So if I have this at a class level
val baseURL = "http://$domainName/endpoint"
and then a function like this
Copy code
fun someMore(domainName : String, somethingElse : String) {
val x = "$baseURL$somethingElse
}
then x should equal http://mydomainname/endpoint/mysomethingElse if I pass in mydomainname and mysomethingelse to the function ?
l
Maybe you can use a lazy delegate?
Copy code
val baseUrl by lazy { "http://$domainName/endpoint" }
it will only be evaluated once it's accessed
But idk if this is what you mean
You can also use a format for that, instead of trying to use the template
"foo".format(..)
p
Yes that's exactly what I mean - great, thanks !
s
To defer the execution of a val, provide a getter:
val baseURL get() = "http://$domainName/endpoint"
Only when called/used the string will be evaluated.
p
I don't think these solutions will work as
$domainName
will be resolved in the original class scope rather than in function scope. One solution I can think of is to turn
baseURL
into a lambda that accepts
domainName
as parameter.
👍 1
p
The get() doesn't work as you get a compile error as the domain name doesn't exist
The lambda solution works - thanks @pniederw
m
This ‘feels’ risky. baseURL will use the domainName available at the moment in time when it’s executed. If
someMore
is called more than once, with a different
domainName
, you won’t get the result you want as baseURL will always return the first value. If someMore IS only called once, then there’s likely a cleaner way to set the
domainName
in baseURL.
s
why not
Copy code
fun baseURL(domainName: String) = 
    "http://$domainName/endpoint"
fun someMore(domainName: String, somethingElse: String) {
    val x = "${baseURL(domainName)}$somethingElse"
}