I have been trying to use extension functions in Kotlin.
class ExtensionExample() {
var name: String? = null
fun Any?.toString() : String {
if (this == null) {
return "Value is null"
}
return "Value is not null"
}
}
When I print the name variable like below
println(ExtensionExample().name.toString())
It should print like
Value is null
But it doesn't print like I expected. It only prints null.
Can someone explain please?
Extension functions have scopes. This is why it is not accessible outside of the ExtensionExample class.
Usually, extension functions are defined as top-level functions. That is, they tend to belong outside of a class.
Your toString extension is defined within ExtensionExample. This is possible, but it means it is only available in the scope of this class, and this class only.
Your main method is likely a top-level function (and not a member of that class), so it doesn't have access to this extension function.
Only other members can access this extension function:
class ExtensionExample {
var name: String? = null
fun Any?.toString(): String {
return if (this == null) "Value is null" else "Value is not null"
}
fun foo() {
println(name.toString())
}
}
fun main(args: Array<String>) {
ExtensionExample().foo()
}
prints "Value is null"
Try it online!
The reason why it compiles is that the toString method that is being called is the Any?.toString method from the kotlin-stdlib. That is, this method already exists.
fun Any?.toString(): StringReturns a string representation of the object. Can be called with a null receiver, in which case it returns the string "null".
Move your extension function out of the class. Your extension function will then hide the stdlib's extension, and any invocation in the same package not explicitly importing kotlin.toString will use your function.
Here is a working version of your code:
class ExtensionExample {
var name: String? = null
}
fun Any?.toString(): String {
return if (this == null) "Value is null" else "Value is not null"
}
fun main(args: Array<String>) {
println(ExtensionExample().name.toString())
}
prints "Value is null", as you wanted.
Try it online!
Note that you cannot hide a member function using an extension function. That is,
class Test {
fun a() {
println("a")
}
}
fun Test.a() {
println("b")
}
...
Test().a()
will result in "a" being printed.
The only reason why your Any?.toString works (after being moved out of the class) is that Any? has no members as it is not a class, but a nullable type with the class Any. The already existing toString method is also an extension, so yours is not hidden by any members.
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