<!DOCTYPE HTML> <html lang="en" class="sidebar-visible no-js"> <head> <!-- Book generated using mdBook --> <meta charset="UTF-8"> <title>Closures - The Rust Programming Language</title> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="theme-color" content="#ffffff" /> <base href=""> <link rel="stylesheet" href="book.css"> <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css"> <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css"> <link rel="shortcut icon" href="favicon.png"> <!-- Font Awesome --> <link rel="stylesheet" href="_FontAwesome/css/font-awesome.css"> <link rel="stylesheet" href="highlight.css"> <link rel="stylesheet" href="tomorrow-night.css"> <link rel="stylesheet" href="ayu-highlight.css"> <!-- Custom theme stylesheets --> <link rel="stylesheet" href="src/theme/first-edition.css"> </head> <body class="light"> <!-- Work around some values being stored in localStorage wrapped in quotes --> <script type="text/javascript"> try { var theme = localStorage.getItem('mdbook-theme'); var sidebar = localStorage.getItem('mdbook-sidebar'); if (theme.startsWith('"') && theme.endsWith('"')) { localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1)); } if (sidebar.startsWith('"') && sidebar.endsWith('"')) { localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1)); } } catch (e) { } </script> <!-- Set the theme before any content is loaded, prevents flash --> <script type="text/javascript"> var theme; try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { } if (theme === null || theme === undefined) { theme = 'light'; } document.body.className = theme; document.querySelector('html').className = theme + ' js'; </script> <!-- Hide / unhide sidebar before it is displayed --> <script type="text/javascript"> var html = document.querySelector('html'); var sidebar = 'hidden'; if (document.body.clientWidth >= 1080) { try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { } sidebar = sidebar || 'visible'; } html.classList.remove('sidebar-visible'); html.classList.add("sidebar-" + sidebar); </script> <nav id="sidebar" class="sidebar" aria-label="Table of contents"> <ol class="chapter"><li class="affix"><a href="README.html">Introduction</a></li><li><a href="getting-started.html"><strong aria-hidden="true">1.</strong> Getting Started</a></li><li><a href="guessing-game.html"><strong aria-hidden="true">2.</strong> Tutorial: Guessing Game</a></li><li><a href="syntax-and-semantics.html"><strong aria-hidden="true">3.</strong> Syntax and Semantics</a></li><li><ol class="section"><li><a href="variable-bindings.html"><strong aria-hidden="true">3.1.</strong> Variable Bindings</a></li><li><a href="functions.html"><strong aria-hidden="true">3.2.</strong> Functions</a></li><li><a href="primitive-types.html"><strong aria-hidden="true">3.3.</strong> Primitive Types</a></li><li><a href="comments.html"><strong aria-hidden="true">3.4.</strong> Comments</a></li><li><a href="if.html"><strong aria-hidden="true">3.5.</strong> if</a></li><li><a href="loops.html"><strong aria-hidden="true">3.6.</strong> Loops</a></li><li><a href="vectors.html"><strong aria-hidden="true">3.7.</strong> Vectors</a></li><li><a href="ownership.html"><strong aria-hidden="true">3.8.</strong> Ownership</a></li><li><a href="references-and-borrowing.html"><strong aria-hidden="true">3.9.</strong> References and Borrowing</a></li><li><a href="lifetimes.html"><strong aria-hidden="true">3.10.</strong> Lifetimes</a></li><li><a href="mutability.html"><strong aria-hidden="true">3.11.</strong> Mutability</a></li><li><a href="structs.html"><strong aria-hidden="true">3.12.</strong> Structs</a></li><li><a href="enums.html"><strong aria-hidden="true">3.13.</strong> Enums</a></li><li><a href="match.html"><strong aria-hidden="true">3.14.</strong> Match</a></li><li><a href="patterns.html"><strong aria-hidden="true">3.15.</strong> Patterns</a></li><li><a href="method-syntax.html"><strong aria-hidden="true">3.16.</strong> Method Syntax</a></li><li><a href="strings.html"><strong aria-hidden="true">3.17.</strong> Strings</a></li><li><a href="generics.html"><strong aria-hidden="true">3.18.</strong> Generics</a></li><li><a href="traits.html"><strong aria-hidden="true">3.19.</strong> Traits</a></li><li><a href="drop.html"><strong aria-hidden="true">3.20.</strong> Drop</a></li><li><a href="if-let.html"><strong aria-hidden="true">3.21.</strong> if let</a></li><li><a href="trait-objects.html"><strong aria-hidden="true">3.22.</strong> Trait Objects</a></li><li><a href="closures.html" class="active"><strong aria-hidden="true">3.23.</strong> Closures</a></li><li><a href="ufcs.html"><strong aria-hidden="true">3.24.</strong> Universal Function Call Syntax</a></li><li><a href="crates-and-modules.html"><strong aria-hidden="true">3.25.</strong> Crates and Modules</a></li><li><a href="const-and-static.html"><strong aria-hidden="true">3.26.</strong> const and static</a></li><li><a href="attributes.html"><strong aria-hidden="true">3.27.</strong> Attributes</a></li><li><a href="type-aliases.html"><strong aria-hidden="true">3.28.</strong> type aliases</a></li><li><a href="casting-between-types.html"><strong aria-hidden="true">3.29.</strong> Casting between types</a></li><li><a href="associated-types.html"><strong aria-hidden="true">3.30.</strong> Associated Types</a></li><li><a href="unsized-types.html"><strong aria-hidden="true">3.31.</strong> Unsized Types</a></li><li><a href="operators-and-overloading.html"><strong aria-hidden="true">3.32.</strong> Operators and Overloading</a></li><li><a href="deref-coercions.html"><strong aria-hidden="true">3.33.</strong> Deref coercions</a></li><li><a href="macros.html"><strong aria-hidden="true">3.34.</strong> Macros</a></li><li><a href="raw-pointers.html"><strong aria-hidden="true">3.35.</strong> Raw Pointers</a></li><li><a href="unsafe.html"><strong aria-hidden="true">3.36.</strong> unsafe</a></li></ol></li><li><a href="effective-rust.html"><strong aria-hidden="true">4.</strong> Effective Rust</a></li><li><ol class="section"><li><a href="the-stack-and-the-heap.html"><strong aria-hidden="true">4.1.</strong> The Stack and the Heap</a></li><li><a href="testing.html"><strong aria-hidden="true">4.2.</strong> Testing</a></li><li><a href="conditional-compilation.html"><strong aria-hidden="true">4.3.</strong> Conditional Compilation</a></li><li><a href="documentation.html"><strong aria-hidden="true">4.4.</strong> Documentation</a></li><li><a href="iterators.html"><strong aria-hidden="true">4.5.</strong> Iterators</a></li><li><a href="concurrency.html"><strong aria-hidden="true">4.6.</strong> Concurrency</a></li><li><a href="error-handling.html"><strong aria-hidden="true">4.7.</strong> Error Handling</a></li><li><a href="choosing-your-guarantees.html"><strong aria-hidden="true">4.8.</strong> Choosing your Guarantees</a></li><li><a href="ffi.html"><strong aria-hidden="true">4.9.</strong> FFI</a></li><li><a href="borrow-and-asref.html"><strong aria-hidden="true">4.10.</strong> Borrow and AsRef</a></li><li><a href="release-channels.html"><strong aria-hidden="true">4.11.</strong> Release Channels</a></li><li><a href="using-rust-without-the-standard-library.html"><strong aria-hidden="true">4.12.</strong> Using Rust without the standard library</a></li><li><a href="procedural-macros.html"><strong aria-hidden="true">4.13.</strong> Procedural Macros (and custom derive)</a></li></ol></li><li><a href="glossary.html"><strong aria-hidden="true">5.</strong> Glossary</a></li><li><a href="syntax-index.html"><strong aria-hidden="true">6.</strong> Syntax Index</a></li><li><a href="bibliography.html"><strong aria-hidden="true">7.</strong> Bibliography</a></li></ol> </nav> <div id="page-wrapper" class="page-wrapper"> <div class="page"> <div id="draft-warning" class="warning"> <span class="message">You are reading an <strong>outdated</strong> edition of TRPL. For more, go <a href="../index.html">here</a>.</span> <button type="button" id="hide-draft-warning" title="Hide draft warning" class="button"> <i class="fa fa-times"></i> </button> </div> <!-- Hide / unhide warning before it is displayed --> <script type="text/javascript"> var warning = localStorage.getItem('trpl-first-edition-draft-warning'); if (warning === 'hidden') { Array .from(document.querySelectorAll('#page-wrapper')) .forEach(function(block) { block.classList.remove('has-warning'); }); var elem = document.getElementById("draft-warning"); elem.parentNode.removeChild(elem); } document.addEventListener("DOMContentLoaded", function(event) { document.getElementById("hide-draft-warning").addEventListener("click", function(e) { var elem = document.getElementById("draft-warning"); elem.parentNode.removeChild(elem); localStorage.setItem('trpl-first-edition-draft-warning', 'hidden'); }); }); </script> <div id="menu-bar" class="menu-bar"> <div id="menu-bar-sticky-container"> <div class="left-buttons"> <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar"> <i class="fa fa-bars"></i> </button> <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list"> <i class="fa fa-paint-brush"></i> </button> <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu"> <li role="none"><button role="menuitem" class="theme" id="light">Light <span class="default">(default)</span></button></li> <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li> <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li> <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li> <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li> </ul> <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar"> <i class="fa fa-search"></i> </button> </div> <h1 class="menu-title">The Rust Programming Language</h1> <div class="right-buttons"> <a href="print.html" title="Print this book" aria-label="Print this book"> <i id="print-button" class="fa fa-print"></i> </a> </div> </div> </div> <div id="search-wrapper" class="hidden"> <form id="searchbar-outer" class="searchbar-outer"> <input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header"> </form> <div id="searchresults-outer" class="searchresults-outer hidden"> <div id="searchresults-header" class="searchresults-header"></div> <ul id="searchresults"> </ul> </div> </div> <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM --> <script type="text/javascript"> document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible'); document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible'); Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) { link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1); }); </script> <div id="content" class="content"> <main> <a class="header" href="closures.html#closures" id="closures"><h1>Closures</h1></a> <p>Sometimes it is useful to wrap up a function and <em>free variables</em> for better clarity and reuse. The free variables that can be used come from the enclosing scope and are ‘closed over’ when used in the function. From this, we get the name ‘closures’ and Rust provides a really great implementation of them, as we’ll see.</p> <a class="header" href="closures.html#syntax" id="syntax"><h1>Syntax</h1></a> <p>Closures look like this:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { let plus_one = |x: i32| x + 1; assert_eq!(2, plus_one(1)); #}</code></pre></pre> <p>We create a binding, <code>plus_one</code>, and assign it to a closure. The closure’s arguments go between the pipes (<code>|</code>), and the body is an expression, in this case, <code>x + 1</code>. Remember that <code>{ }</code> is an expression, so we can have multi-line closures too:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { let plus_two = |x| { let mut result: i32 = x; result += 1; result += 1; result }; assert_eq!(4, plus_two(2)); #}</code></pre></pre> <p>You’ll notice a few things about closures that are a bit different from regular named functions defined with <code>fn</code>. The first is that we did not need to annotate the types of arguments the closure takes or the values it returns. We can:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { let plus_one = |x: i32| -> i32 { x + 1 }; assert_eq!(2, plus_one(1)); #}</code></pre></pre> <p>But we don’t have to. Why is this? Basically, it was chosen for ergonomic reasons. While specifying the full type for named functions is helpful with things like documentation and type inference, the full type signatures of closures are rarely documented since they’re anonymous, and they don’t cause the kinds of error-at-a-distance problems that inferring named function types can.</p> <p>The second is that the syntax is similar, but a bit different. I’ve added spaces here for easier comparison:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { fn plus_one_v1 (x: i32) -> i32 { x + 1 } let plus_one_v2 = |x: i32| -> i32 { x + 1 }; let plus_one_v3 = |x: i32| x + 1 ; #}</code></pre></pre> <p>Small differences, but they’re similar.</p> <a class="header" href="closures.html#closures-and-their-environment" id="closures-and-their-environment"><h1>Closures and their environment</h1></a> <p>The environment for a closure can include bindings from its enclosing scope in addition to parameters and local bindings. It looks like this:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { let num = 5; let plus_num = |x: i32| x + num; assert_eq!(10, plus_num(5)); #}</code></pre></pre> <p>This closure, <code>plus_num</code>, refers to a <code>let</code> binding in its scope: <code>num</code>. More specifically, it borrows the binding. If we do something that would conflict with that binding, we get an error. Like this one:</p> <pre><code class="language-rust ignore">let mut num = 5; let plus_num = |x: i32| x + num; let y = &mut num; </code></pre> <p>Which errors with:</p> <pre><code class="language-text">error: cannot borrow `num` as mutable because it is also borrowed as immutable let y = &mut num; ^~~ note: previous borrow of `num` occurs here due to use in closure; the immutable borrow prevents subsequent moves or mutable borrows of `num` until the borrow ends let plus_num = |x| x + num; ^~~~~~~~~~~ note: previous borrow ends here fn main() { let mut num = 5; let plus_num = |x| x + num; let y = &mut num; } ^ </code></pre> <p>A verbose yet helpful error message! As it says, we can’t take a mutable borrow on <code>num</code> because the closure is already borrowing it. If we let the closure go out of scope, we can:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { let mut num = 5; { let plus_num = |x: i32| x + num; } // `plus_num` goes out of scope; borrow of `num` ends. let y = &mut num; #}</code></pre></pre> <p>If your closure requires it, however, Rust will take ownership and move the environment instead. This doesn’t work:</p> <pre><code class="language-rust ignore">let nums = vec![1, 2, 3]; let takes_nums = || nums; println!("{:?}", nums); </code></pre> <p>We get this error:</p> <pre><code class="language-text">note: `nums` moved into closure environment here because it has type `[closure(()) -> collections::vec::Vec<i32>]`, which is non-copyable let takes_nums = || nums; ^~~~~~~ </code></pre> <p><code>Vec<T></code> has ownership over its contents, and therefore, when we refer to it in our closure, we have to take ownership of <code>nums</code>. It’s the same as if we’d passed <code>nums</code> to a function that took ownership of it.</p> <a class="header" href="closures.html#move-closures" id="move-closures"><h2><code>move</code> closures</h2></a> <p>We can force our closure to take ownership of its environment with the <code>move</code> keyword:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { let num = 5; let owns_num = move |x: i32| x + num; #}</code></pre></pre> <p>Now, even though the keyword is <code>move</code>, the variables follow normal move semantics. In this case, <code>5</code> implements <code>Copy</code>, and so <code>owns_num</code> takes ownership of a copy of <code>num</code>. So what’s the difference?</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { let mut num = 5; { let mut add_num = |x: i32| num += x; add_num(5); } assert_eq!(10, num); #}</code></pre></pre> <p>So in this case, our closure took a mutable reference to <code>num</code>, and then when we called <code>add_num</code>, it mutated the underlying value, as we’d expect. We also needed to declare <code>add_num</code> as <code>mut</code> too, because we’re mutating its environment.</p> <p>If we change to a <code>move</code> closure, it’s different:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { let mut num = 5; { let mut add_num = move |x: i32| num += x; add_num(5); } assert_eq!(5, num); #}</code></pre></pre> <p>We only get <code>5</code>. Rather than taking a mutable borrow out on our <code>num</code>, we took ownership of a copy.</p> <p>Another way to think about <code>move</code> closures: they give a closure its own stack frame. Without <code>move</code>, a closure may be tied to the stack frame that created it, while a <code>move</code> closure is self-contained. This means that you cannot generally return a non-<code>move</code> closure from a function, for example.</p> <p>But before we talk about taking and returning closures, we should talk some more about the way that closures are implemented. As a systems language, Rust gives you tons of control over what your code does, and closures are no different.</p> <a class="header" href="closures.html#closure-implementation" id="closure-implementation"><h1>Closure implementation</h1></a> <p>Rust’s implementation of closures is a bit different than other languages. They are effectively syntax sugar for traits. You’ll want to make sure to have read the <a href="traits.html">traits</a> section before this one, as well as the section on <a href="trait-objects.html">trait objects</a>.</p> <p>Got all that? Good.</p> <p>The key to understanding how closures work under the hood is something a bit strange: Using <code>()</code> to call a function, like <code>foo()</code>, is an overloadable operator. From this, everything else clicks into place. In Rust, we use the trait system to overload operators. Calling functions is no different. We have three separate traits to overload with:</p> <ul> <li><code>Fn</code></li> <li><code>FnMut</code></li> <li><code>FnOnce</code></li> </ul> <p>There are a few differences between these traits, but a big one is <code>self</code>: <code>Fn</code> takes <code>&self</code>, <code>FnMut</code> takes <code>&mut self</code>, and <code>FnOnce</code> takes <code>self</code>. This covers all three kinds of <code>self</code> via the usual method call syntax. But we’ve split them up into three traits, rather than having a single one. This gives us a large amount of control over what kind of closures we can take.</p> <p>The <code>|| {}</code> syntax for closures is sugar for these three traits. Rust will generate a struct for the environment, <code>impl</code> the appropriate trait, and then use it.</p> <a class="header" href="closures.html#taking-closures-as-arguments" id="taking-closures-as-arguments"><h1>Taking closures as arguments</h1></a> <p>Now that we know that closures are traits, we already know how to accept and return closures: the same as any other trait!</p> <p>This also means that we can choose static vs dynamic dispatch as well. First, let’s write a function which takes something callable, calls it, and returns the result:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { fn call_with_one<F>(some_closure: F) -> i32 where F: Fn(i32) -> i32 { some_closure(1) } let answer = call_with_one(|x| x + 2); assert_eq!(3, answer); #}</code></pre></pre> <p>We pass our closure, <code>|x| x + 2</code>, to <code>call_with_one</code>. It does what it suggests: it calls the closure, giving it <code>1</code> as an argument.</p> <p>Let’s examine the signature of <code>call_with_one</code> in more depth:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { fn call_with_one<F>(some_closure: F) -> i32 # where F: Fn(i32) -> i32 { # some_closure(1) } #}</code></pre></pre> <p>We take one parameter, and it has the type <code>F</code>. We also return an <code>i32</code>. This part isn’t interesting. The next part is:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { # fn call_with_one<F>(some_closure: F) -> i32 where F: Fn(i32) -> i32 { # some_closure(1) } #}</code></pre></pre> <p>Because <code>Fn</code> is a trait, we can use it as a bound for our generic type. In this case, our closure takes an <code>i32</code> as an argument and returns an <code>i32</code>, and so the generic bound we use is <code>Fn(i32) -> i32</code>.</p> <p>There’s one other key point here: because we’re bounding a generic with a trait, this will get monomorphized, and therefore, we’ll be doing static dispatch into the closure. That’s pretty neat. In many languages, closures are inherently heap allocated, and will always involve dynamic dispatch. In Rust, we can stack allocate our closure environment, and statically dispatch the call. This happens quite often with iterators and their adapters, which often take closures as arguments.</p> <p>Of course, if we want dynamic dispatch, we can get that too. A trait object handles this case, as usual:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { fn call_with_one(some_closure: &Fn(i32) -> i32) -> i32 { some_closure(1) } let answer = call_with_one(&|x| x + 2); assert_eq!(3, answer); #}</code></pre></pre> <p>Now we take a trait object, a <code>&Fn</code>. And we have to make a reference to our closure when we pass it to <code>call_with_one</code>, so we use <code>&||</code>.</p> <p>A quick note about closures that use explicit lifetimes. Sometimes you might have a closure that takes a reference like so:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { fn call_with_ref<F>(some_closure:F) -> i32 where F: Fn(&i32) -> i32 { let value = 0; some_closure(&value) } #}</code></pre></pre> <p>Normally you can specify the lifetime of the parameter to our closure. We could annotate it on the function declaration:</p> <pre><code class="language-rust ignore">fn call_with_ref<'a, F>(some_closure:F) -> i32 where F: Fn(&'a i32) -> i32 { </code></pre> <p>However, this presents a problem in our case. When a function has an explicit lifetime parameter, that lifetime must be at least as long as the <em>entire</em> call to that function. The borrow checker will complain that <code>value</code> doesn't live long enough, because it is only in scope after its declaration inside the function body.</p> <p>What we need is a closure that can borrow its argument only for its own invocation scope, not for the outer function's scope. In order to say that, we can use Higher-Ranked Trait Bounds with the <code>for<...></code> syntax:</p> <pre><code class="language-ignore">fn call_with_ref<F>(some_closure:F) -> i32 where F: for<'a> Fn(&'a i32) -> i32 { </code></pre> <p>This lets the Rust compiler find the minimum lifetime to invoke our closure and satisfy the borrow checker's rules. Our function then compiles and executes as we expect.</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { fn call_with_ref<F>(some_closure:F) -> i32 where F: for<'a> Fn(&'a i32) -> i32 { let value = 0; some_closure(&value) } #}</code></pre></pre> <a class="header" href="closures.html#function-pointers-and-closures" id="function-pointers-and-closures"><h1>Function pointers and closures</h1></a> <p>A function pointer is kind of like a closure that has no environment. As such, you can pass a function pointer to any function expecting a closure argument, and it will work:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { fn call_with_one(some_closure: &Fn(i32) -> i32) -> i32 { some_closure(1) } fn add_one(i: i32) -> i32 { i + 1 } let f = add_one; let answer = call_with_one(&f); assert_eq!(2, answer); #}</code></pre></pre> <p>In this example, we don’t strictly need the intermediate variable <code>f</code>, the name of the function works just fine too:</p> <pre><code class="language-rust ignore">let answer = call_with_one(&add_one); </code></pre> <a class="header" href="closures.html#returning-closures" id="returning-closures"><h1>Returning closures</h1></a> <p>It’s very common for functional-style code to return closures in various situations. If you try to return a closure, you may run into an error. At first, it may seem strange, but we’ll figure it out. Here’s how you’d probably try to return a closure from a function:</p> <pre><code class="language-rust ignore">fn factory() -> (Fn(i32) -> i32) { let num = 5; |x| x + num } let f = factory(); let answer = f(1); assert_eq!(6, answer); </code></pre> <p>This gives us these long, related errors:</p> <pre><code class="language-text">error: the trait bound `core::ops::Fn(i32) -> i32 : core::marker::Sized` is not satisfied [E0277] fn factory() -> (Fn(i32) -> i32) { ^~~~~~~~~~~~~~~~ note: `core::ops::Fn(i32) -> i32` does not have a constant size known at compile-time fn factory() -> (Fn(i32) -> i32) { ^~~~~~~~~~~~~~~~ error: the trait bound `core::ops::Fn(i32) -> i32 : core::marker::Sized` is not satisfied [E0277] let f = factory(); ^ note: `core::ops::Fn(i32) -> i32` does not have a constant size known at compile-time let f = factory(); ^ </code></pre> <p>In order to return something from a function, Rust needs to know what size the return type is. But since <code>Fn</code> is a trait, it could be various things of various sizes: many different types can implement <code>Fn</code>. An easy way to give something a size is to take a reference to it, as references have a known size. So we’d write this:</p> <pre><code class="language-rust ignore">fn factory() -> &(Fn(i32) -> i32) { let num = 5; |x| x + num } let f = factory(); let answer = f(1); assert_eq!(6, answer); </code></pre> <p>But we get another error:</p> <pre><code class="language-text">error: missing lifetime specifier [E0106] fn factory() -> &(Fn(i32) -> i32) { ^~~~~~~~~~~~~~~~~ </code></pre> <p>Right. Because we have a reference, we need to give it a lifetime. But our <code>factory()</code> function takes no arguments, so <a href="lifetimes.html#lifetime-elision">elision</a> doesn’t kick in here. Then what choices do we have? Try <code>'static</code>:</p> <pre><code class="language-rust ignore">fn factory() -> &'static (Fn(i32) -> i32) { let num = 5; |x| x + num } let f = factory(); let answer = f(1); assert_eq!(6, answer); </code></pre> <p>But we get another error:</p> <pre><code class="language-text">error: mismatched types: expected `&'static core::ops::Fn(i32) -> i32`, found `[closure@<anon>:7:9: 7:20]` (expected &-ptr, found closure) [E0308] |x| x + num ^~~~~~~~~~~ </code></pre> <p>This error is letting us know that we don’t have a <code>&'static Fn(i32) -> i32</code>, we have a <code>[closure@<anon>:7:9: 7:20]</code>. Wait, what?</p> <p>Because each closure generates its own environment <code>struct</code> and implementation of <code>Fn</code> and friends, these types are anonymous. They exist solely for this closure. So Rust shows them as <code>closure@<anon></code>, rather than some autogenerated name.</p> <p>The error also points out that the return type is expected to be a reference, but what we are trying to return is not. Further, we cannot directly assign a <code>'static</code> lifetime to an object. So we'll take a different approach and return a ‘trait object’ by <code>Box</code>ing up the <code>Fn</code>. This <em>almost</em> works:</p> <pre><code class="language-rust ignore">fn factory() -> Box<Fn(i32) -> i32> { let num = 5; Box::new(|x| x + num) } let f = factory(); let answer = f(1); assert_eq!(6, answer); </code></pre> <p>There’s just one last problem:</p> <pre><code class="language-text">error: closure may outlive the current function, but it borrows `num`, which is owned by the current function [E0373] Box::new(|x| x + num) ^~~~~~~~~~~ </code></pre> <p>Well, as we discussed before, closures borrow their environment. And in this case, our environment is based on a stack-allocated <code>5</code>, the <code>num</code> variable binding. So the borrow has a lifetime of the stack frame. So if we returned this closure, the function call would be over, the stack frame would go away, and our closure is capturing an environment of garbage memory! With one last fix, we can make this work:</p> <pre><pre class="playpen"><code class="language-rust"> # #![allow(unused_variables)] #fn main() { fn factory() -> Box<Fn(i32) -> i32> { let num = 5; Box::new(move |x| x + num) } let f = factory(); let answer = f(1); assert_eq!(6, answer); #}</code></pre></pre> <p>By making the inner closure a <code>move Fn</code>, we create a new stack frame for our closure. By <code>Box</code>ing it up, we’ve given it a known size, allowing it to escape our stack frame.</p> </main> <nav class="nav-wrapper" aria-label="Page navigation"> <!-- Mobile navigation buttons --> <a rel="prev" href="trait-objects.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <i class="fa fa-angle-left"></i> </a> <a rel="next" href="ufcs.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <i class="fa fa-angle-right"></i> </a> <div style="clear: both"></div> </nav> </div> </div> <nav class="nav-wide-wrapper" aria-label="Page navigation"> <a href="trait-objects.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <i class="fa fa-angle-left"></i> </a> <a href="ufcs.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <i class="fa fa-angle-right"></i> </a> </nav> </div> <script src="searchindex.js" type="text/javascript" charset="utf-8"></script> <script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script> <script src="mark.min.js" type="text/javascript" charset="utf-8"></script> <script src="searcher.js" type="text/javascript" charset="utf-8"></script> <script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script> <script src="highlight.js" type="text/javascript" charset="utf-8"></script> <script src="book.js" type="text/javascript" charset="utf-8"></script> <!-- Custom JS scripts --> </body> </html>