Kotlin this

Kotlin this

1. Overview

In this article, we will discuss Kotlin this expression with a few examples to make it simpler and easier to understand.

2. Kotlin this in class

In short, this keyword points to the current scope.

Consider we have a Student class that has the name and department instance variables. It also has a print method to print the name value. Now let’s create an instance temp for the Student class inside the main function. Then call the print function using the temp instance.

Here, this expression inside the print function points to the enclosing instance or object temp. You can access your current scope variables using this keyword inside the class.

class Student(private var name: String, private var department: String) {
   fun resetStudent(name:String, department: String) {
       this.name = name 
       this.department = department 
   }
   fun print() {
       println(name) 
   }
} 
fun main() {
   val temp = Student("GK", "CS") 
   temp.print()
   temp.resetStudent("JB", "IT")
   temp.print()
}

The this keyword helps to eliminate the confusion between class variables and parameters with the same name. The parameters of the methods or constructors of a class can have the same name as one of the class’s fields. In this case, we say the parameter shadows the field, meaning the parameter takes precedence.

In the above code, resetStudent method contains parameters that exactly match the class variables. So, inside it, any name or department reference without this always points to the parameter scope. For example, name refers to parameter variable name whereas this.name refers to the class instance variable.

However, we can omit this inside the print function as there are no variable conflicts like in resetStudent function.

2. Kotlin this in Extension function

The this keyword points to the current receiver of the extension function. Extension function allows to add more functionality to the existing classes, without inheriting them or using any design patterns.

We declare the extension function by using a prefix receiver type (class name) followed by a dot and then the name of the extension function. The receiver refers to the class being extended.

Let’s take an extension function example.

In the below code, we are adding a new extension function getFileFormat to the String class that can take a file name as input and returns the file format (txt, jpg,..). We can invoke this function from our code on any String object.

Here, the receiver or class type is String. Inside the main function, we have a fileName string variable and we are calling getFileFormat extension function on the fileName string.

Now, this keyword inside the extension function refers to the fileName receiver object (the one passed before the dot).

fun String.getFileFormat(): String {
  return this.substringAfterLast('.', "")
}
fun main() {
    val fileName= "sample.txt"
    val result = fileName.getFileFormat()
    println("File format is: $result")
}

3. Qualified this in Kotlin

Assume you have an inner class B inside the outer class A like below. Here, we have two scopes: outer class scope and inner class scope. See our article on Kotlin nested and inner class to know about the Kotlin inner class.

Class B has a function foo that prints the square of the value c. Now, c refers to the B’s variable c. What if you want to refer to the A’s variable c. How can you refer to the outer class variables from your inner class scope?

class A { 
    private val c = 10
    inner class B { 
        private val c = 20
        fun foo() { 
            val result = c*c
        }
    }
} 

Qualified this (this@label) helps us to achieve it by allowing us to refer to the scope we want. The implicit label for the scope would be the class or function name.

Let’s see the below examples to understand this better.

3.1. Qualified this for class scope

In the below code, we have two classes A and B. A class is the outer scope class with implicit label @A (class name) whereas B class is the inner class scope with implicit label @B.

Inside the foo function, qualified this@A points to the outer class A and this@B points to the inner class B.

class A { 
    inner class B { 
        fun foo() { 
            val a = this@A 
            val b = this@B 
        }
    }
}

3.2. Qualified this for extension function

In the below example, foo is an extension function for the receiver Int. Therefore, the name of the extension function @foo is the implicit label here and this@foo would refer to the receiver object.

class A { 
    inner class B { 
        fun Int.foo() { 
            val a = this@A 
            val b = this@B 
            val c = this 
            val c1 = this@foo 
        }
    }
}

4. Implicit this in Kotlin

You can skip when you call a member function on this or refer to the innermost scope variables.

In the below code, we have skipped this for the reference name inside the print function as there are no conflicts. It implicitly refers to the current object.

class Student(private var name: String, private var department: String) {
   fun print() {
       println(name) 
   }
} 
fun main() {
   val temp = Student("GK", "CS") 
   temp.print()
}

In the below code, we skipped this keyword while referring to the current receiver object. Even without this keyword, the subStringAfterLast implicitly points to the current receiver object and execute on it.

fun String.getFileFormat(): String =  substringAfterLast('.', "")
fun main(args: Array<String>) {
    val filename= "sample.txt"
    val result = filename.getFileFormat()
    println("File format is: $result")
}

5. Conclusion

In this article, we have discussed the Kotlin this with examples.

Leave a Comment

error: Content is protected !!