Question regarding extension functions in the documentation

Hi, I was following Kotlin Koans “Extension functions on collections”,
and just got a little bit confused while looking at the documentation kotlin.collections - Kotlin Programming Language

Here in the link, are all functions here extension functions?
In the documentation, in general, how can one distinguish between extension functions and member functions?

Not all of them are. You can tell which ones are by looking at the function declaration code blocks.

Extension functions will look like this:

fun Type.functionName(): Type

And other functions will look like this:

fun functionName(): Type

First of all, extension functions and member functions are not mutually exclusive, you could have a member function that is an extension function.

Now, you can identify extension functions because they will have a receiver type, i.e. receiverType.functionName().

If there is a function that is both a member function and an extension function, which one is called when we call it? Is there an example of this kind of function in the standard library?
And for these kind of functions, then are there both types of declarations stated in the documentation? e.g.

fun Type.functionName(): Type
fun functionName(): Type

You misinterpreted his statement. Member functions can also be extension functions like in this example:

class Foo {
    fun String.twice() = this + this

    fun demo() = print("Foo".twice())
}

fun main() = Foo().demo()

Here, twice() is a member function of class Foo and an extension function of type String. It can be called only if both a Foo and String instance are available in the context. Both instances are available within the function body via this and labeled this expressions.

2 Likes

Thank you for the reply.

I found that here ClosedRange - Kotlin Programming Language
there are both parts Functions and Extension Functions, with the same function name contains.

Functions

contains

Checks whether the specified value belongs to the range.

open operator fun contains(value: T): Boolean

Extension Functions

contains

Checks if the specified value belongs to this range.

operator fun ClosedRange<Int>.contains(value: Byte): Boolean

operator fun ClosedRange<Long>.contains(value: Byte): Boolean

operator fun ClosedRange<Short>.contains(value: Byte): Boolean

operator fun ClosedRange<Double>.contains(value: Byte): Boolean

...

Can someone explain this case?

  • there are also some strikethrough text for some of them, which the editor in this site doesn’t support. What does the strikethrough mean?

Doesn’t that mean “deprecated”?

Yes, these functions should not be used anymore.
On the website, below the example, it states the reason.

Extension functions are just normal functions:

fun addTwoTimesTo(initial: Int, toAdd : Int) = 
     initial+toAdd+toAdd
fun subtractTwoTimesTo(initial : Int, minus: Int) =
    initial - minus - minus

let’s test using oneLiner:

fun shouldGetSameValue(
     initial : Int, 
     operation: Int
)  = addTwoTimesTo(
    subtractTwoTimes(initial, operation), 
    operation
)

I find this difficult to read. This function would way better if we could call it on initial, doesn’t it?

Well, we can check this by using extension-functions. Oh and to to let it look even more like we are adding it to the Int-class, let’s reference to initial using this.
Then you will get:

fun Int.addTwoTimes(toAdd: Int) = this + toAdd + toAdd
fun Int.subtractTwoTimes(minus : Int) = this - minus - minus

Now we can rewrite the test:

fun shouldGetSameValue(
     initial : Int, 
     operation: Int
)  = initial.addTwoTimes(operation)
           .subtractTwoTimes(operation) 

We only changed the looks. It’s still the same as the first function.
Do note:

  • Extension functions don’t care about inheritance. If you store a Child in a variabel of type Parent and have extension functions for both Child and Parent, the parent function will be called.
  • a function actually declared on a class will always winn from an extension-function.
  • as the function changes only the looks, you can’t suddenly get access to private functions/fields inside the class.
1 Like