Open In App

Function Literals with Receiver in Kotlin

Last Updated : 06 Dec, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

In Kotlin, functions are first-class citizens. It means that functions can be assigned to the variables, passed as an argument, or returned from another function. While Kotlin is statically typed, to make it possible, functions need to have a type. It exists and it is called function type and these are:

  • val wish: ()->Unit
  • val sum: (Int)->Int
  • val something: ()->()->Unit

Prerequisites for this Article:

Function reference is an example of reflection. It returns a reference to the function which also implements an interface that represents a function type. This is why it can be used this way. Generally, literal in programming is a cube of syntactic sugar for representing values of some types the language considers particularly important. Therefore function literal is a special notation used to simplify how a function is defined. There are two types of function literals in Kotlin:

Introduction

A Function literal is a function that is not declared but that is passed in as an expression. Lambdas and anonymous functions are function literals. In Kotlin, we can call a function literal with a receiver object, and we can call methods on the receiver object inside the body of the function literal, quite like extension functions. In this article, we will learn how to use function literals with receivers.

Example: Follow these steps to understand function literals:

Let’s start with a simple function literal on a string, which returns a string added to the receiver string:

Kotlin




fun main (args: Array<String>) {
  var s = "gonna do "
  val addS = fun String. (successor: String) : String {
    return this + successor
  }
  s = s . addS ("nothing much.")
  printIn (s)
}


A function literal has access to the receiver it has been called on, and it can access methods associated with that receiver. We can also pass the receiver as a parameter in an ordinary function, where the first parameter is for a receiver. This can be useful in scenarios where we need to use an ordinary function, So String. (String) -> Int is similar to (String, String) -> Int is compatible. Check out the following example:

Kotlin




fun main (args: Array<String>) {
  var s = "gonna do "
  val addS = fun String. (successor: String) : Int {
    return this . length + successor . length
      }
    var x = s. addS ("nothing  much.")
    printin (x)
    fun testIfEqual (op: (String, String) -> Int, a: String, b:String, c: Int) =
  assert (op (a, b) == c)
    test IfEqual (addS, "gonna do ","nothing much. ",
                  s . length + "nothing     much.". length)
}


If the receiver type can be inferred, then lambda can be used as the function literal. So basically, we can call a function literal on a receiver object, and inside the body of the function, we can access and call methods on a receiver object, similar to an extension function in Kotlin. The following is the syntax for this:

receiver . functionLliteral (arguments) -> ReturnType



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads