![Kotlin this](https://tedblob.com/wp-content/uploads/2021/09/image-6-1024x301.png)
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 invoke the print
function using the 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.name refers to the class variable this.department = department // this.department refers to the class variable } fun print() { println(name) } } fun main() { val temp = Student("GK", "CS") // Here, we create a instance of Student class. 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 the function, any reference to name
or department
by default points to the parameter scope. For example, name
refers to parameter variable name
whereas this.name
refers to the class instance variable.
However, you 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.
fun String.getFileFormat(): String { return this.substringAfterLast('.', "") }
In the above 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.
fun main() { val fileName= "sample.txt" val result = fileName.getFileFormat() println("File format is: $result") }
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).
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 { // implicit label @A inner class B { // implicit label @B fun foo() { val a = this@A // A's this val b = this@B // B's this } } }
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 { // implicit label @A inner class B { // implicit label @B fun Int.foo() { // implicit label @foo val a = this@A // A's this val b = this@B // B's this val c = this // foo()'s receiver, an Int val c1 = this@foo // foo()'s receiver, an Int } } }
4. Implicit this in Kotlin
You can skip when you call a member function on thi
s 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") // Here, we create a instance of Student class. 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.