CINXE.COM

Higher-order functions and lambdas | Kotlin Documentation

<!DOCTYPE html SYSTEM "about:legacy-compat"> <html lang="en-US" data-preset="contrast" data-primary-color="#307FFF"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="UTF-8"><meta name="built-on" content="2024-11-18T21:26:18.129891668"><meta name="build-number" content="3272"><script> (function (w, d, s, l, i) { w[l] = w[l] || []; w[l].push({'gtm.start': new Date().getTime(), event: 'gtm.js'}); var f = d.getElementsByTagName(s)[0], j = d.createElement(s), dl = l != 'dataLayer' ? '&amp;l=' + l : ''; j.async = true; j.src = '//www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); })(window, document, 'script', 'dataLayer', 'GTM-5P98'); </script> <script src="static/v3/analytics.js"></script> <title>Higher-order functions and lambdas | Kotlin Documentation</title><script type="application/json" id="virtual-toc-data">[{"id":"higher-order-functions","level":0,"title":"Higher-order functions","anchor":"#higher-order-functions"},{"id":"function-types","level":0,"title":"Function types","anchor":"#function-types"},{"id":"instantiating-a-function-type","level":1,"title":"Instantiating a function type","anchor":"#instantiating-a-function-type"},{"id":"invoking-a-function-type-instance","level":1,"title":"Invoking a function type instance","anchor":"#invoking-a-function-type-instance"},{"id":"inline-functions","level":1,"title":"Inline functions","anchor":"#inline-functions"},{"id":"lambda-expressions-and-anonymous-functions","level":0,"title":"Lambda expressions and anonymous functions","anchor":"#lambda-expressions-and-anonymous-functions"},{"id":"lambda-expression-syntax","level":1,"title":"Lambda expression syntax","anchor":"#lambda-expression-syntax"},{"id":"passing-trailing-lambdas","level":1,"title":"Passing trailing lambdas","anchor":"#passing-trailing-lambdas"},{"id":"it-implicit-name-of-a-single-parameter","level":1,"title":"it: implicit name of a single parameter","anchor":"#it-implicit-name-of-a-single-parameter"},{"id":"returning-a-value-from-a-lambda-expression","level":1,"title":"Returning a value from a lambda expression","anchor":"#returning-a-value-from-a-lambda-expression"},{"id":"underscore-for-unused-variables","level":1,"title":"Underscore for unused variables","anchor":"#underscore-for-unused-variables"},{"id":"destructuring-in-lambdas","level":1,"title":"Destructuring in lambdas","anchor":"#destructuring-in-lambdas"},{"id":"anonymous-functions","level":1,"title":"Anonymous functions","anchor":"#anonymous-functions"},{"id":"closures","level":1,"title":"Closures","anchor":"#closures"},{"id":"function-literals-with-receiver","level":1,"title":"Function literals with receiver","anchor":"#function-literals-with-receiver"}]</script><script type="application/json" id="topic-shortcuts"></script><link href="static/v3/app.css?v=6.11.0-footer" rel="stylesheet"><link rel="icon" type="image/svg" sizes="16x16" href="https://kotlinlang.org/assets/images/favicon.svg?v2"><link rel="icon" type="image/x-icon" sizes="32x32" href="https://kotlinlang.org/assets/images/favicon.ico?v2"><link rel="icon" type="image/png" sizes="96x96" href="https://kotlinlang.org/assets/images/apple-touch-icon.png?v2"><link rel="icon" type="image/png" sizes="300x300" href="https://kotlinlang.org/assets/images/apple-touch-icon-72x72.png?v2"><link rel="icon" type="image/png" sizes="500x500" href="https://kotlinlang.org/assets/images/apple-touch-icon-114x114.png?v2"><meta name="image" content="https://kotlinlang.org/assets/images/open-graph/docs.png"><!-- Open Graph --><meta property="og:title" content="Higher-order functions and lambdas | Kotlin"><meta property="og:description" content=""><meta property="og:image" content="https://kotlinlang.org/assets/images/open-graph/docs.png"><meta property="og:site_name" content="Kotlin Help"><meta property="og:type" content="website"><meta property="og:locale" content="en_US"><meta property="og:url" content="https://kotlinlang.org/docs/lambdas.html"><!-- End Open Graph --><!-- Twitter Card --><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@kotlin"><meta name="twitter:title" content="Higher-order functions and lambdas | Kotlin"><meta name="twitter:description" content=""><meta name="twitter:creator" content="@kotlin"><meta name="twitter:image:src" content="https://kotlinlang.org/assets/images/open-graph/docs.png"><!-- End Twitter Card --><!-- Schema.org WebPage --><script type="application/ld+json">{ "@context": "http://schema.org", "@type": "WebPage", "@id": "https://kotlinlang.org/docs/lambdas.html#webpage", "url": "https://kotlinlang.org/docs/lambdas.html", "name": "Higher-order functions and lambdas | Kotlin", "description": "", "image": "https://kotlinlang.org/assets/images/open-graph/docs.png", "inLanguage":"en-US" }</script><!-- End Schema.org --><!-- Schema.org WebSite --><script type="application/ld+json">{ "@type": "WebSite", "@id": "https://kotlinlang.org/docs/#website", "url": "https://kotlinlang.org/docs/", "name": "Kotlin Help" }</script><!-- End Schema.org --><style>a[href="test-page.html"] { visibility: hidden; }</style></head><body data-id="lambdas" data-main-title="Higher-order functions and lambdas" data-article-props="{&quot;seeAlsoStyle&quot;:&quot;links&quot;}" data-template="article" data-breadcrumbs="Concepts///Functions" data-edit-url="https://github.com/JetBrains/kotlin-web-site/edit/master/docs/topics/lambdas.md"><div class="wrapper"><main class="panel _main"><header class="panel__header"><div class="container"><h3>Kotlin Help</h3><div class="panel-trigger"></div></div></header><section class="panel__content"><div class="container"><article class="article" data-shortcut-switcher="inactive"><h1 data-toc="lambdas" id="lambdas.md">Higher-order functions and lambdas</h1><p id="-38ft6s_2">Kotlin functions are <a href="https://en.wikipedia.org/wiki/First-class_function" id="-38ft6s_7" data-external="true" rel="noopener noreferrer">first-class</a>, which means they can be stored in variables and data structures, and can be passed as arguments to and returned from other <a href="#higher-order-functions" id="-38ft6s_8">higher-order functions</a>. You can perform any operations on functions that are possible for other non-function values.</p><p id="-38ft6s_3">To facilitate this, Kotlin, as a statically typed programming language, uses a family of <a href="#function-types" id="-38ft6s_9">function types</a> to represent functions, and provides a set of specialized language constructs, such as <a href="#lambda-expressions-and-anonymous-functions" id="-38ft6s_10">lambda expressions</a>.</p><section class="chapter"><h2 id="higher-order-functions" data-toc="higher-order-functions">Higher-order functions</h2><p id="-38ft6s_11">A higher-order function is a function that takes functions as parameters, or returns a function.</p><p id="-38ft6s_12">A good example of a higher-order function is the <a href="https://en.wikipedia.org/wiki/Fold_(higher-order_function)" id="-38ft6s_17" data-external="true" rel="noopener noreferrer">functional programming idiom <code class="code" id="-38ft6s_18">fold</code></a> for collections. It takes an initial accumulator value and a combining function and builds its return value by consecutively combining the current accumulator value with each collection element, replacing the accumulator value each time:</p><div class="code-block" data-lang="kotlin"> fun &lt;T, R&gt; Collection&lt;T&gt;.fold( initial: R, combine: (acc: R, nextElement: T) -&gt; R ): R { var accumulator: R = initial for (element: T in this) { accumulator = combine(accumulator, element) } return accumulator } </div><p id="-38ft6s_14">In the code above, the <code class="code" id="-38ft6s_19">combine</code> parameter has the <a href="#function-types" id="-38ft6s_20">function type</a> <code class="code" id="-38ft6s_21">(R, T) -&gt; R</code>, so it accepts a function that takes two arguments of types <code class="code" id="-38ft6s_22">R</code> and <code class="code" id="-38ft6s_23">T</code> and returns a value of type <code class="code" id="-38ft6s_24">R</code>. It is <a href="#invoking-a-function-type-instance" id="-38ft6s_25">invoked</a> inside the <code class="code" id="-38ft6s_26">for</code> loop, and the return value is then assigned to <code class="code" id="-38ft6s_27">accumulator</code>.</p><p id="-38ft6s_15">To call <code class="code" id="-38ft6s_28">fold</code>, you need to pass an <a href="#instantiating-a-function-type" id="-38ft6s_29">instance of the function type</a> to it as an argument, and lambda expressions (<a href="#lambda-expressions-and-anonymous-functions" id="-38ft6s_30">described in more detail below</a>) are widely used for this purpose at higher-order function call sites:</p><div class="code-block" data-lang="kotlin" data-runnable="true"> fun main() { //sampleStart val items = listOf(1, 2, 3, 4, 5) // Lambdas are code blocks enclosed in curly braces. items.fold(0, { // When a lambda has parameters, they go first, followed by '-&gt;' acc: Int, i: Int -&gt; print(&quot;acc = $acc, i = $i, &quot;) val result = acc + i println(&quot;result = $result&quot;) // The last expression in a lambda is considered the return value: result }) // Parameter types in a lambda are optional if they can be inferred: val joinedToString = items.fold(&quot;Elements:&quot;, { acc, i -&gt; acc + &quot; &quot; + i }) // Function references can also be used for higher-order function calls: val product = items.fold(1, Int::times) //sampleEnd println(&quot;joinedToString = $joinedToString&quot;) println(&quot;product = $product&quot;) } </div></section><section class="chapter"><h2 id="function-types" data-toc="function-types">Function types</h2><p id="-38ft6s_31">Kotlin uses function types, such as <code class="code" id="-38ft6s_43">(Int) -&gt; String</code>, for declarations that deal with functions: <code class="code" id="-38ft6s_44">val onClick: () -&gt; Unit = ...</code>.</p><p id="-38ft6s_32">These types have a special notation that corresponds to the signatures of the functions - their parameters and return values:</p><ul class="list _bullet" id="-38ft6s_33"><li class="list__item" id="-38ft6s_45"><p id="-38ft6s_48">All function types have a parenthesized list of parameter types and a return type: <code class="code" id="-38ft6s_49">(A, B) -&gt; C</code> denotes a type that represents functions that take two arguments of types <code class="code" id="-38ft6s_50">A</code> and <code class="code" id="-38ft6s_51">B</code> and return a value of type <code class="code" id="-38ft6s_52">C</code>. The list of parameter types may be empty, as in <code class="code" id="-38ft6s_53">() -&gt; A</code>. The <a href="functions.html#unit-returning-functions" id="-38ft6s_54"><code class="code" id="-38ft6s_55">Unit</code> return type</a> cannot be omitted.</p></li><li class="list__item" id="-38ft6s_46"><p id="-38ft6s_56">Function types can optionally have an additional <span class="emphasis" id="-38ft6s_57">receiver</span> type, which is specified before the dot in the notation: the type <code class="code" id="-38ft6s_58">A.(B) -&gt; C</code> represents functions that can be called on a receiver object <code class="code" id="-38ft6s_59">A</code> with a parameter <code class="code" id="-38ft6s_60">B</code> and return a value <code class="code" id="-38ft6s_61">C</code>. <a href="#function-literals-with-receiver" id="-38ft6s_62">Function literals with receiver</a> are often used along with these types.</p></li><li class="list__item" id="-38ft6s_47"><p id="-38ft6s_63"><a href="coroutines-basics.html#extract-function-refactoring" id="-38ft6s_64" data-tooltip="Let's extract the block of code inside launch { ... } into a separate function. When you perform &quot;Extract function&quot; refactoring on this code, you get a new function with the suspend modifier. This is your first suspending function. Suspending functions can be used inside…">Suspending functions</a> belong to a special kind of function type that have a <span class="emphasis" id="-38ft6s_65">suspend</span> modifier in their notation, such as <code class="code" id="-38ft6s_66">suspend () -&gt; Unit</code> or <code class="code" id="-38ft6s_67">suspend A.(B) -&gt; C</code>.</p></li></ul><p id="-38ft6s_34">The function type notation can optionally include names for the function parameters: <code class="code" id="-38ft6s_68">(x: Int, y: Int) -&gt; Point</code>. These names can be used for documenting the meaning of the parameters.</p><p id="-38ft6s_35">To specify that a function type is <a href="null-safety.html#nullable-types-and-non-nullable-types" id="-38ft6s_69">nullable</a>, use parentheses as follows: <code class="code" id="-38ft6s_70">((Int, Int) -&gt; Int)?</code>.</p><p id="-38ft6s_36">Function types can also be combined using parentheses: <code class="code" id="-38ft6s_71">(Int) -&gt; ((Int) -&gt; Unit)</code>.</p><aside class="prompt" data-type="note" data-title="" id="-38ft6s_37"><p id="-38ft6s_72">The arrow notation is right-associative, <code class="code" id="-38ft6s_73">(Int) -&gt; (Int) -&gt; Unit</code> is equivalent to the previous example, but not to <code class="code" id="-38ft6s_74">((Int) -&gt; (Int)) -&gt; Unit</code>.</p></aside><p id="-38ft6s_38">You can also give a function type an alternative name by using <a href="type-aliases.html" id="-38ft6s_75">a type alias</a>:</p><div class="code-block" data-lang="kotlin"> typealias ClickHandler = (Button, ClickEvent) -&gt; Unit </div><section class="chapter"><h3 id="instantiating-a-function-type" data-toc="instantiating-a-function-type">Instantiating a function type</h3><p id="-38ft6s_76">There are several ways to obtain an instance of a function type:</p><ul class="list _bullet" id="-38ft6s_77"><li class="list__item" id="-38ft6s_84"><p id="-38ft6s_87">Use a code block within a function literal, in one of the following forms:</p><ul class="list _bullet" id="-38ft6s_88"><li class="list__item" id="-38ft6s_90"><p>a <a href="#lambda-expressions-and-anonymous-functions" id="-38ft6s_92">lambda expression</a>: <code class="code" id="-38ft6s_93">{ a, b -&gt; a + b }</code>,</p></li><li class="list__item" id="-38ft6s_91"><p>an <a href="#anonymous-functions" id="-38ft6s_94">anonymous function</a>: <code class="code" id="-38ft6s_95">fun(s: String): Int { return s.toIntOrNull() ?: 0 }</code></p></li></ul><p id="-38ft6s_89"><a href="#function-literals-with-receiver" id="-38ft6s_96">Function literals with receiver</a> can be used as values of function types with receiver.</p></li><li class="list__item" id="-38ft6s_85"><p id="-38ft6s_97">Use a callable reference to an existing declaration:</p><ul class="list _bullet" id="-38ft6s_98"><li class="list__item" id="-38ft6s_100"><p>a top-level, local, member, or extension <a href="reflection.html#function-references" id="-38ft6s_103">function</a>: <code class="code" id="-38ft6s_104">::isOdd</code>, <code class="code" id="-38ft6s_105">String::toInt</code>,</p></li><li class="list__item" id="-38ft6s_101"><p>a top-level, member, or extension <a href="reflection.html#property-references" id="-38ft6s_106">property</a>: <code class="code" id="-38ft6s_107">List&lt;Int&gt;::size</code>,</p></li><li class="list__item" id="-38ft6s_102"><p>a <a href="reflection.html#constructor-references" id="-38ft6s_108">constructor</a>: <code class="code" id="-38ft6s_109">::Regex</code></p></li></ul><p id="-38ft6s_99">These include <a href="reflection.html#bound-function-and-property-references" id="-38ft6s_110">bound callable references</a> that point to a member of a particular instance: <code class="code" id="-38ft6s_111">foo::toString</code>.</p></li><li class="list__item" id="-38ft6s_86"><p id="-38ft6s_112">Use instances of a custom class that implements a function type as an interface:</p></li></ul><div class="code-block" data-lang="kotlin"> class IntTransformer: (Int) -&gt; Int { override operator fun invoke(x: Int): Int = TODO() } val intFunction: (Int) -&gt; Int = IntTransformer() </div><p id="-38ft6s_79">The compiler can infer the function types for variables if there is enough information:</p><div class="code-block" data-lang="kotlin"> val a = { i: Int -&gt; i + 1 } // The inferred type is (Int) -&gt; Int </div><p id="-38ft6s_81"><span class="emphasis" id="-38ft6s_113">Non-literal</span> values of function types with and without a receiver are interchangeable, so the receiver can stand in for the first parameter, and vice versa. For instance, a value of type <code class="code" id="-38ft6s_114">(A, B) -&gt; C</code> can be passed or assigned where a value of type <code class="code" id="-38ft6s_115">A.(B) -&gt; C</code> is expected, and the other way around:</p><div class="code-block" data-lang="kotlin" data-runnable="true"> fun main() { //sampleStart val repeatFun: String.(Int) -&gt; String = { times -&gt; this.repeat(times) } val twoParameters: (String, Int) -&gt; String = repeatFun // OK fun runTransformation(f: (String, Int) -&gt; String): String { return f(&quot;hello&quot;, 3) } val result = runTransformation(repeatFun) // OK //sampleEnd println(&quot;result = $result&quot;) } </div><aside class="prompt" data-type="note" data-title="" id="-38ft6s_83"><p id="-38ft6s_116">A function type with no receiver is inferred by default, even if a variable is initialized with a reference to an extension function. To alter that, specify the variable type explicitly.</p></aside></section><section class="chapter"><h3 id="invoking-a-function-type-instance" data-toc="invoking-a-function-type-instance">Invoking a function type instance</h3><p id="-38ft6s_117">A value of a function type can be invoked by using its <a href="operator-overloading.html#invoke-operator" id="-38ft6s_121"><code class="code" id="-38ft6s_124">invoke(...)</code> operator</a>: <code class="code" id="-38ft6s_122">f.invoke(x)</code> or just <code class="code" id="-38ft6s_123">f(x)</code>.</p><p id="-38ft6s_118">If the value has a receiver type, the receiver object should be passed as the first argument. Another way to invoke a value of a function type with receiver is to prepend it with the receiver object, as if the value were an <a href="extensions.html" id="-38ft6s_125">extension function</a>: <code class="code" id="-38ft6s_126">1.foo(2)</code>.</p><p id="-38ft6s_119">Example:</p><div class="code-block" data-lang="kotlin" data-runnable="true"> fun main() { //sampleStart val stringPlus: (String, String) -&gt; String = String::plus val intPlus: Int.(Int) -&gt; Int = Int::plus println(stringPlus.invoke(&quot;&lt;-&quot;, &quot;-&gt;&quot;)) println(stringPlus(&quot;Hello, &quot;, &quot;world!&quot;)) println(intPlus.invoke(1, 1)) println(intPlus(1, 2)) println(2.intPlus(3)) // extension-like call //sampleEnd } </div></section><section class="chapter"><h3 id="inline-functions" data-toc="inline-functions">Inline functions</h3><p id="-38ft6s_127">Sometimes it is beneficial to use <a href="inline-functions.html" id="-38ft6s_128">inline functions</a>, which provide flexible control flow, for higher-order functions.</p></section></section><section class="chapter"><h2 id="lambda-expressions-and-anonymous-functions" data-toc="lambda-expressions-and-anonymous-functions">Lambda expressions and anonymous functions</h2><p id="-38ft6s_129">Lambda expressions and anonymous functions are <span class="emphasis" id="-38ft6s_142">function literals</span>. Function literals are functions that are not declared but are passed immediately as an expression. Consider the following example:</p><div class="code-block" data-lang="kotlin"> max(strings, { a, b -&gt; a.length &lt; b.length }) </div><p id="-38ft6s_131">The function <code class="code" id="-38ft6s_143">max</code> is a higher-order function, as it takes a function value as its second argument. This second argument is an expression that is itself a function, called a function literal, which is equivalent to the following named function:</p><div class="code-block" data-lang="kotlin"> fun compare(a: String, b: String): Boolean = a.length &lt; b.length </div><section class="chapter"><h3 id="lambda-expression-syntax" data-toc="lambda-expression-syntax">Lambda expression syntax</h3><p id="-38ft6s_144">The full syntactic form of lambda expressions is as follows:</p><div class="code-block" data-lang="kotlin"> val sum: (Int, Int) -&gt; Int = { x: Int, y: Int -&gt; x + y } </div><ul class="list _bullet" id="-38ft6s_146"><li class="list__item" id="-38ft6s_149"><p>A lambda expression is always surrounded by curly braces.</p></li><li class="list__item" id="-38ft6s_150"><p>Parameter declarations in the full syntactic form go inside curly braces and have optional type annotations.</p></li><li class="list__item" id="-38ft6s_151"><p>The body goes after the <code class="code" id="-38ft6s_153">-&gt;</code>.</p></li><li class="list__item" id="-38ft6s_152"><p>If the inferred return type of the lambda is not <code class="code" id="-38ft6s_154">Unit</code>, the last (or possibly single) expression inside the lambda body is treated as the return value.</p></li></ul><p id="-38ft6s_147">If you leave all the optional annotations out, what's left looks like this:</p><div class="code-block" data-lang="kotlin"> val sum = { x: Int, y: Int -&gt; x + y } </div></section><section class="chapter"><h3 id="passing-trailing-lambdas" data-toc="passing-trailing-lambdas">Passing trailing lambdas</h3><p id="-38ft6s_155">According to Kotlin convention, if the last parameter of a function is a function, then a lambda expression passed as the corresponding argument can be placed outside the parentheses:</p><div class="code-block" data-lang="kotlin"> val product = items.fold(1) { acc, e -&gt; acc * e } </div><p id="-38ft6s_157">Such syntax is also known as <span class="emphasis" id="-38ft6s_160">trailing lambda</span>.</p><p id="-38ft6s_158">If the lambda is the only argument in that call, the parentheses can be omitted entirely:</p><div class="code-block" data-lang="kotlin"> run { println(&quot;...&quot;) } </div></section><section class="chapter"><h3 id="it-implicit-name-of-a-single-parameter" data-toc="it-implicit-name-of-a-single-parameter">it: implicit name of a single parameter</h3><p id="-38ft6s_161">It's very common for a lambda expression to have only one parameter.</p><p id="-38ft6s_162">If the compiler can parse the signature without any parameters, the parameter does not need to be declared and <code class="code" id="-38ft6s_164">-&gt;</code> can be omitted. The parameter will be implicitly declared under the name <code class="code" id="-38ft6s_165">it</code>:</p><div class="code-block" data-lang="kotlin"> ints.filter { it &gt; 0 } // this literal is of type '(it: Int) -&gt; Boolean' </div></section><section class="chapter"><h3 id="returning-a-value-from-a-lambda-expression" data-toc="returning-a-value-from-a-lambda-expression">Returning a value from a lambda expression</h3><p id="-38ft6s_166">You can explicitly return a value from the lambda using the <a href="returns.html#return-to-labels" id="-38ft6s_171">qualified return</a> syntax. Otherwise, the value of the last expression is implicitly returned.</p><p id="-38ft6s_167">Therefore, the two following snippets are equivalent:</p><div class="code-block" data-lang="kotlin"> ints.filter { val shouldFilter = it &gt; 0 shouldFilter } ints.filter { val shouldFilter = it &gt; 0 return@filter shouldFilter } </div><p id="-38ft6s_169">This convention, along with <a href="#passing-trailing-lambdas" id="-38ft6s_172">passing a lambda expression outside of parentheses</a>, allows for <a href="https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/" id="-38ft6s_173" data-external="true" rel="noopener noreferrer">LINQ-style</a> code:</p><div class="code-block" data-lang="kotlin"> strings.filter { it.length == 5 }.sortedBy { it }.map { it.uppercase() } </div></section><section class="chapter"><h3 id="underscore-for-unused-variables" data-toc="underscore-for-unused-variables">Underscore for unused variables</h3><p id="-38ft6s_174">If the lambda parameter is unused, you can place an underscore instead of its name:</p><div class="code-block" data-lang="kotlin"> map.forEach { (_, value) -&gt; println(&quot;$value!&quot;) } </div></section><section class="chapter"><h3 id="destructuring-in-lambdas" data-toc="destructuring-in-lambdas">Destructuring in lambdas</h3><p id="-38ft6s_176">Destructuring in lambdas is described as a part of <a href="destructuring-declarations.html#destructuring-in-lambdas" id="-38ft6s_177">destructuring declarations</a>.</p></section><section class="chapter"><h3 id="anonymous-functions" data-toc="anonymous-functions">Anonymous functions</h3><p id="-38ft6s_178">The lambda expression syntax above is missing one thing &ndash; the ability to specify the function's return type. In most cases, this is unnecessary because the return type can be inferred automatically. However, if you do need to specify it explicitly, you can use an alternative syntax: an <span class="emphasis" id="-38ft6s_187">anonymous function</span>.</p><div class="code-block" data-lang="kotlin"> fun(x: Int, y: Int): Int = x + y </div><p id="-38ft6s_180">An anonymous function looks very much like a regular function declaration, except its name is omitted. Its body can be either an expression (as shown above) or a block:</p><div class="code-block" data-lang="kotlin"> fun(x: Int, y: Int): Int { return x + y } </div><p id="-38ft6s_182">The parameters and the return type are specified in the same way as for regular functions, except the parameter types can be omitted if they can be inferred from the context:</p><div class="code-block" data-lang="kotlin"> ints.filter(fun(item) = item &gt; 0) </div><p id="-38ft6s_184">The return type inference for anonymous functions works just like for normal functions: the return type is inferred automatically for anonymous functions with an expression body, but it has to be specified explicitly (or is assumed to be <code class="code" id="-38ft6s_188">Unit</code>) for anonymous functions with a block body.</p><aside class="prompt" data-type="note" data-title="" id="-38ft6s_185"><p id="-38ft6s_189">When passing anonymous functions as parameters, place them inside the parentheses. The shorthand syntax that allows you to leave the function outside the parentheses works only for lambda expressions.</p></aside><p id="-38ft6s_186">Another difference between lambda expressions and anonymous functions is the behavior of <a href="inline-functions.html#non-local-returns" id="-38ft6s_190">non-local returns</a>. A <code class="code" id="-38ft6s_191">return</code> statement without a label always returns from the function declared with the <code class="code" id="-38ft6s_192">fun</code> keyword. This means that a <code class="code" id="-38ft6s_193">return</code> inside a lambda expression will return from the enclosing function, whereas a <code class="code" id="-38ft6s_194">return</code> inside an anonymous function will return from the anonymous function itself.</p></section><section class="chapter"><h3 id="closures" data-toc="closures">Closures</h3><p id="-38ft6s_195">A lambda expression or anonymous function (as well as a <a href="functions.html#local-functions" id="-38ft6s_197">local function</a> and an <a href="object-declarations.html#object-expressions" id="-38ft6s_198">object expression</a>) can access its <span class="emphasis" id="-38ft6s_199">closure</span>, which includes the variables declared in the outer scope. The variables captured in the closure can be modified in the lambda:</p><div class="code-block" data-lang="kotlin"> var sum = 0 ints.filter { it &gt; 0 }.forEach { sum += it } print(sum) </div></section><section class="chapter"><h3 id="function-literals-with-receiver" data-toc="function-literals-with-receiver">Function literals with receiver</h3><p id="-38ft6s_200"><a href="#function-types" id="-38ft6s_210">Function types</a> with receiver, such as <code class="code" id="-38ft6s_211">A.(B) -&gt; C</code>, can be instantiated with a special form of function literals &ndash; function literals with receiver.</p><p id="-38ft6s_201">As mentioned above, Kotlin provides the ability <a href="#invoking-a-function-type-instance" id="-38ft6s_212">to call an instance</a> of a function type with receiver while providing the <span class="emphasis" id="-38ft6s_213">receiver object</span>.</p><p id="-38ft6s_202">Inside the body of the function literal, the receiver object passed to a call becomes an <span class="emphasis" id="-38ft6s_214">implicit</span> <code class="code" id="-38ft6s_215">this</code>, so that you can access the members of that receiver object without any additional qualifiers, or access the receiver object using a <a href="this-expressions.html" id="-38ft6s_216"><code class="code" id="-38ft6s_217">this</code> expression</a>.</p><p id="-38ft6s_203">This behavior is similar to that of <a href="extensions.html" id="-38ft6s_218">extension functions</a>, which also allow you to access the members of the receiver object inside the function body.</p><p id="-38ft6s_204">Here is an example of a function literal with receiver along with its type, where <code class="code" id="-38ft6s_219">plus</code> is called on the receiver object:</p><div class="code-block" data-lang="kotlin"> val sum: Int.(Int) -&gt; Int = { other -&gt; plus(other) } </div><p id="-38ft6s_206">The anonymous function syntax allows you to specify the receiver type of a function literal directly. This can be useful if you need to declare a variable of a function type with receiver, and then to use it later.</p><div class="code-block" data-lang="kotlin"> val sum = fun Int.(other: Int): Int = this + other </div><p id="-38ft6s_208">Lambda expressions can be used as function literals with receiver when the receiver type can be inferred from the context. One of the most important examples of their usage is <a href="type-safe-builders.html" id="-38ft6s_220">type-safe builders</a>:</p><div class="code-block" data-lang="kotlin"> class HTML { fun body() { ... } } fun html(init: HTML.() -&gt; Unit): HTML { val html = HTML() // create the receiver object html.init() // pass the receiver object to the lambda return html } html { // lambda with receiver begins here body() // calling a method on the receiver object } </div></section></section><div class="last-modified">Last modified: 25 September 2024</div><div data-feedback-placeholder="true"></div><div class="navigation-links _bottom"><a href="functions.html" class="navigation-links__prev">Functions</a><a href="inline-functions.html" class="navigation-links__next">Inline functions</a></div></article><div id="disqus_thread"></div></div></section></main></div><script src="static/v3/app.js"></script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10