The question is in the comment. I want to refer to the outer function append
, and not the one that's defined in the StringBuilder
, how do I do this?
fun append(c: Char) {
println("TEST")
}
fun sbTest() = with(StringBuilder()) {
for(c in 'A'..'Z') {
append(c) // how do I refer to the append function declared above?
}
toString()
}
I know I can introduce a function reference variable, like this:
val f = ::append
and call f
instead of append
, but is there another way?
The problem is that anything called within with
shadows the outer functions, because this
is introduced. The same problem appears if you have a class and a top-level function with a function with the same signature.
The obvious option would just be re-naming it. Also, the function you have there isn't really descriptive compared to what it actually does. But if you for some reason can't rename, there are still other options.
Top-level methods can be referenced by package in Kotlin, for an instance like com.some.package.method
. It can also be imported as such, which is the most common way to do it. There are very few methods that are called as com.some.package.method()
.
Kotlin, like Python, allows as
in imports. Which means, you can do this:
package com.example;
// This is the important line; it declares the import with a custom name.
import com.example.append as appendChar; // Just an example name; this could be anything ***except append***. If it's append, it defeats the purpose
fun append(c: Char) {
println("TEST")
}
fun sbTest() = with(StringBuilder()) {
for(c in 'A'..'Z') {
appendChar(c)
}
toString()
}
Alternatively, as I mentioned, you can add the package:
for(c in 'A'..'Z') {
com.example.append(c)
}
val f = ::append
is of course an option too, either way, it is still easier to rename the function than create imports with as
or constants, assuming you have access to the function (and that it doesn't belong to a dependency).
If your file is outside a package, which I do not recommend you do, you can just declare the import as:
import append as appendChar
You could also use an extension function instead of with()
, such as .let{...}
.
This will send StringBuilder
as an argument to the extension function as it
(You can rename it to whatever you want btw):
fun sbTest() = StringBuilder().let{ it ->
for(c in 'A'..'Z') {
// using string builder
it.append(c)
// using your function
append(c)
}
it.toString()
}
The .let{...}
function returns your last statement, aka the String from toString()
, so your original function would still return it properly. Other functions can return this
instead, such as .also{...}
I tend to use extension functions rather than with()
as they're more flexible.
See this post to master extension functions: https://medium.com/@elye.project/mastering-kotlin-standard-functions-run-with-let-also-and-apply-9cd334b0ef84
EDIT: Got also{}
and let{}
mixed up. I switched them
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With