{"id":2311,"date":"2022-03-09T08:14:19","date_gmt":"2022-03-09T14:14:19","guid":{"rendered":"https:\/\/www.becomebetterprogrammer.com\/?p=2311"},"modified":"2022-04-25T09:32:29","modified_gmt":"2022-04-25T14:32:29","slug":"rust-question-mark-operator","status":"publish","type":"post","link":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/rust-question-mark-operator\/","title":{"rendered":"Rust: What is the Question Mark (?) Operator?"},"content":{"rendered":"\n<p>Rust is an excellent alternative for programmers who want to discover why it is one of the most loved programming languages. Despite being one of the most enjoyable languages to work with, there are syntaxes that might be confusing or won&#8217;t make too much sense when you look at Rust code and you are new to working with this language, such as understanding the purpose of a question mark (?).<\/p>\n\n\n\n<p>If you have a JavaScript background, you probably have seen the question mark to enable optional chaining. In other words, to optionally access properties of objects which values can be empty. Notice the <code>team<\/code> variable in the following example doesn&#8217;t have a <code>players<\/code> property. However, we attempt to access a method from the <code>players<\/code> property as if this property exists in the <code>team<\/code> object.  <\/p>\n\n\n\n<pre class=\"wp-block-code language-javascript\"><code>const team = {\n    league: \"La Liga\",\n    name: \"Real Madrid\"\n};\nteam.players?.getTotalSalary();<\/code><\/pre>\n\n\n\n<p>Without using the question mark <code>?<\/code>, the code will crash. However, the question mark enables optional chaining which prevents the code crashing, even if we attempt to access the method <code>getTotalSalary()<\/code> from a property that doesn&#8217;t exist in an object. While concepts such as chaining might work &#8220;kind of similar&#8221; in Rust, the question mark doesn&#8217;t work in the same way in Rust.<\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/rust-question-mark-operator\/#What_is_the_question_mark_operator_in_Rust\" >What is the question mark (?) operator in Rust?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/rust-question-mark-operator\/#Understanding_Error_Propagation\" >Understanding Error Propagation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/rust-question-mark-operator\/#Using_the_Question_Mark_Operator\" >Using the Question Mark (?) Operator<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/rust-question-mark-operator\/#When_and_Where_to_Use_the_Question_Mark_Operator\" >When and Where to Use the Question Mark (?) Operator?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/rust-question-mark-operator\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_is_the_question_mark_operator_in_Rust\"><\/span>What is the question mark (?) operator in Rust?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><strong>The question mark (<code>?<\/code>) operator in Rust is used as an error propagation alternative to functions that return <code>Result<\/code> or <code>Option<\/code> types. The <code>?<\/code> operator is a shortcut as it reduces the amount of code needed to immediately return <code>Err<\/code> or <code>None<\/code> from the types <code>Result&lt;T, Err&gt;<\/code> or <code>Option<\/code>  in a function.<\/strong><\/p>\n\n\n\n<p>After reading the definition of the question mark operator, it won&#8217;t make much sense if we don&#8217;t understand what we mean by error propagation in Rust. In this article, we will show a simple error propagation example as well as how the <code>?<\/code> operator can reduce the amount of code but still maintain the same logic. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Understanding_Error_Propagation\"><\/span>Understanding Error Propagation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Before we move forward with explaining the <code>?<\/code> mark operator, do you know what error propagation is? <\/p>\n\n\n\n<p><strong>Error propagation is the process of &#8220;<em>propagating<\/em>&#8220;, spreading up or returning error information detected in the code generally triggered by a caller function to allow the caller function to properly handle the problem. <\/strong><\/p>\n\n\n\n<p>Let&#8217;s look at how error propagation works in code using the following example.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>fn main() {\n    let value = find_char_index_in_first_word(&amp;\"Learning the question mark\", &amp;'i');\n\n    println!(\"What is the value {}\", value.unwrap_or(1))\n}\n\n\nfn find_char_index_in_first_word(text: &amp;str, char: &amp;char) -&gt; Option&lt;usize&gt; {\n    let first_word =  match text.split(\" \").next().is_some() == true {\n        true =&gt; text.split(\" \").next().unwrap(),\n        false =&gt; return None\n    };\n\n    first_word.find(|x| &amp;x == char)\n}<\/code><\/pre>\n\n\n\n<p>Notice we have a simple helper function called <code>find_char_index_in_first_word<\/code> that returns the index of character found in the first word detected on a string literal. <\/p>\n\n\n\n<p>Having said that, if the string literal is <em>Learning the question mark<\/em> and the character we want to detect is <em>i<\/em>, then the returned index value will be <code>Some(5)<\/code> because the first word of the string literal is <em>Learning<\/em>, which contains the character <em>i<\/em> in position 5 of the array of characters.<\/p>\n\n\n\n<p>Hence, if we run the previous logic, there shouldn&#8217;t be any errors. However, the <code>find_char_index_in_first_word<\/code> could return <code>Option::None<\/code> because the return type definition is <code>Option&lt;&gt;<\/code>. Hence, the caller function is in charge of properly extracting the <code>Option&lt;&gt;<\/code> value.<\/p>\n\n\n\n<p>To see an example of when the value returned is <code>None<\/code>, we can update the string literal passed ot the <code>find_char_index_in_first_word<\/code> to <code>Hello World<\/code> as the word <code>Hello<\/code> doesn&#8217;t have an <em>i<\/em> character.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>fn main() {\n    let value = find_char_index_in_first_word(&amp;\"Hello World\", &amp;'i');\n\n    println!(\"What is the value {}\", value.unwrap_or(1))\n}<\/code><\/pre>\n\n\n\n<p><strong>To extract the value of an <code>Option&lt;&gt;<\/code>, you can use the <code>unwrap()<\/code> method. However, this method can panic or trigger an error if the value attempting to extract is <code>None<\/code><\/strong>. That&#8217;s why we use a safer alternative method called <code>unwrap_or()<\/code> in the <code>main<\/code> function to prevent the code from crashing as it uses instead a default value when <code>value<\/code> is <code>None<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>println!(\"What is the value {}\", value.unwrap_or(1))<\/code><\/pre>\n\n\n\n<p>Hence, the printed value that you should see in the terminal is <em>What is the value 1<\/em> after executing this code.<\/p>\n\n\n\n<p>One aspect worth mentioning in this error propagation explanation is the fact that we are returning a value of type <code>Option<\/code>. <code>Option<\/code> is a type that can either be <code>Some<\/code> or <code>None<\/code>, as you will see in the definition below. However, none of these two possible values are errors themselves.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>pub enum Option&lt;T&gt; {\n    \/\/\/ No value\n    #&#91;lang = \"None\"]\n    #&#91;stable(feature = \"rust1\", since = \"1.0.0\")]\n    None,\n    \/\/\/ Some value `T`\n    #&#91;lang = \"Some\"]\n    #&#91;stable(feature = \"rust1\", since = \"1.0.0\")]\n    Some(#&#91;stable(feature = \"rust1\", since = \"1.0.0\")] T),\n}<\/code><\/pre>\n\n\n\n<p>While it is correct that none of the values returned are errors, different to the <code>Result&lt;T, Err&gt;<\/code> type, where the <code>Err<\/code> type is clearly defined as the error, the option <code>None<\/code> is often used to report errors.<\/p>\n\n\n\n<p>Remember how we use the <code>find()<\/code> method in the <code>find_char_index_in_first_word<\/code> function? To refresh our memory, let&#8217;s look at the definition of this method.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>The <code>find()<\/code> method takes a closure that returns <code>true<\/code> or <code>false<\/code>. It applies this closure to each element of the iterator, and if any of them return <code>true<\/code>, then find() returns <code>Some(element)<\/code>. If they all return <code>false<\/code>, it returns <code>None<\/code>.<\/p><cite><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.find\" target=\"_blank\" rel=\"noopener\">Rust documentation<\/a><\/cite><\/blockquote>\n\n\n\n<p>In other words, the <code>find()<\/code> method returns <code>None<\/code> as a way to say:<em> There was an error. The value you attempted to find doesn&#8217;t exist.<\/em> Hence, we are in some way or another propagating the error as the function <code>find_char_index_in_first_word<\/code> was meant to return a <code>Some(&lt;usize&gt;)<\/code> value.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Using_the_Question_Mark_Operator\"><\/span>Using the Question Mark (<code>?<\/code>) Operator<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>We will show two different ways to define the function <code>find_char_index_in_first_word<\/code> using the <code>?<\/code> operator. Remember what was the original function definition? Let&#8217;s check it out one more time.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>fn find_char_index_in_first_word(text: &amp;str, char: &amp;char) -&gt; Option&lt;usize&gt; {\n    let first_word =  match text.split(\" \").next().is_some() == true {\n        true =&gt; text.split(\" \").next().unwrap(),\n        false =&gt; return None\n    };\n\n    first_word.find(|x| &amp;x == char)\n}<\/code><\/pre>\n\n\n\n<p>We use <code>match<\/code>, before <em>splitting<\/em> the <code>text<\/code> string literal and using the <code>next()<\/code> method to advance the iterator, with the purpose of determining whether the iteration has finished or not by checking if the value is <code>Some(item)<\/code>.<\/p>\n\n\n\n<p>On one hand, if the iterator is <code>Some(item)<\/code>, we unwrap the value of <code>Some(item)<\/code>, which is used later in the code with the <code>find<\/code> method to find the index of the character <code>char<\/code>.<\/p>\n\n\n\n<p>On the other hand, if the iterator is <code>None<\/code>, the function won&#8217;t execute subsequent lines of code as it  will return <code>None<\/code> to the caller function.<\/p>\n\n\n\n<p>We can achieve the same using the <code>?<\/code> operator. The <code>?<\/code> operator returns <code>None<\/code> whenever there is the value is not <code>Some&lt;usize&gt;<\/code>. <\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>fn find_char_index_in_first_word(text: &amp;str, char: &amp;char) -&gt; Option&lt;usize&gt; {\n    let first_word = text.split(\" \").next()?;\n    let index = first_word.find(|x| &amp;x == char)?;\n\n   Some(index)\n}<\/code><\/pre>\n\n\n\n<p>There are a couple of things to look for from checking the code that gets the value of <code>first_word<\/code> or <code>text.split(\" \").next()?<\/code><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>There is no need to unwrap the <code>Option<\/code> value returned after triggering <code>next()<\/code><\/li><li>There is no need to use the <code>return<\/code> keyword to return <code>None<\/code><\/li><\/ol>\n\n\n\n<p>The <code>?<\/code> operator magically extracts the value of the next iterator if the value is <code>Some(item)<\/code>. <\/p>\n\n\n\n<p>In the case the next iterator is <code>None<\/code>, it will behave as <code>return None<\/code>, which prevents executing any additional logic written in the function and immediately return <code>None<\/code> to the caller function.<\/p>\n\n\n\n<p>If we look further down the code in the function, the index variable works in a similar way.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>let index = first_word.find(|x| &amp;x == char)?;<\/code><\/pre>\n\n\n\n<p>If the method <code>find()<\/code> returns <code>Some(element)<\/code>, it will extract the value from <code>Some(index)<\/code> and assign the value <code>element<\/code> to the <code>index<\/code> variable. If it doesn&#8217;t find anything that meets the condition defined in the closure, it returns <code>None<\/code> to the caller function.<\/p>\n\n\n\n<p>Look at another variation of <code>find_char_index_in_first_word<\/code> method.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>fn find_char_index_in_first_word(text: &amp;str, char: &amp;char) -&gt; Option&lt;usize&gt; {\n    Some(text.split(\" \").next()?.find(|x| &amp;x == char)?)\n}<\/code><\/pre>\n\n\n\n<p>Notice we are executing the same logic from the original <code>find_char_index_in_first_word<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>\/\/ long way without using question mark operator ?\nfn find_char_index_in_first_word(text: &amp;str, char: &amp;char) -&gt; Option&lt;usize&gt; {\n    let first_word =  match text.split(\" \").next().is_some() == true {\n        true =&gt; text.split(\" \").next().unwrap(),\n        false =&gt; return None\n    };\n\n    first_word.find(|x| &amp;x == char)\n}\n\n\/\/ understanding the ? question mark error propagation\nfn find_char_index_in_first_word(text: &amp;str, char: &amp;char) -&gt; Option&lt;usize&gt; {\n    let first_word = text.split(\" \").next()?;\n    first_word.find(|x| &amp;x == char)\n}\n\n\/\/ Shortcut\nfn find_char_index_in_first_word(text: &amp;str, char: &amp;char) -&gt; Option&lt;usize&gt; {\n    Some(text.split(\" \").next()?.find(|x| &amp;x == char)?)\n}<\/code><\/pre>\n\n\n\n<p>Notice how <strong>the <code>?<\/code> operator is often referred to as a shortcut for propagating errors<\/strong>. We went from having 4 lines of code to 2 lines of code. We even converted it into one line of code in our latest version of the <code>find_char_index_in_first_word<\/code> function because the <code>?<\/code> allows us to chain the logic, even if we come across at any point with the values <code>None<\/code> or <code>Err<\/code>, as <code>?<\/code> operator will take care of it by returning the error right away.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"When_and_Where_to_Use_the_Question_Mark_Operator\"><\/span>When and Where to Use the Question Mark (<code>?<\/code>) Operator?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Unfortunately, there are scenarios where you can or cannot use the question mark <code>?<\/code> operator. As mentioned in the definition,<strong> the <code>?<\/code> operator is used only in functions that return <code>Result<\/code> or <code>Option<\/code> types<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>fn my_fn_one() -&gt; Result&lt;i32, ParseIntError&gt; {}\nfn my_fn_two() -&gt; Option&lt;usize&gt; {}<\/code><\/pre>\n\n\n\n<p>This doesn&#8217;t mean it is not possible to work with <code>Result<\/code> and <code>Option<\/code> types inside a function. However, the <code>?<\/code> operator should exclusively be used with types that return the same type in a function. <\/p>\n\n\n\n<p>In other words, <strong>if the function returns <code>Result<\/code>, use the <code>?<\/code> operator in a <code>Result<\/code> type. If the function returns an <code>Option<\/code>, use the <code>?<\/code> operator in an <code>Option<\/code> type<\/strong>.<\/p>\n\n\n\n<p>Attempting to use the <code>?<\/code> operator in both types, <code>Result<\/code> and <code>Option<\/code>, in a function that only returns one of the two types will lead to errors. For example, if we were to write the following code:<\/p>\n\n\n\n<pre class=\"wp-block-code language-rust\"><code>fn bad_fn() -&gt; Result&lt;i32, String&gt; {\n    let b = Ok(\"Got it!\")?;\n    let a = Some(1)?;\n\n    Ok(a)\n}<\/code><\/pre>\n\n\n\n<p>Trying to run it will cause the following error:<\/p>\n\n\n\n<p><code>the <code>?<\/code> operator can only be used on <code>Result<\/code>s, not <code>Option<\/code>s, in a function that returns <code>Result<\/code><\/code><\/p>\n\n\n\n<p>Remember, the <code>?<\/code> is a shortcut for error propagation. <\/p>\n\n\n\n<p>If the <code>?<\/code> is used in a type different from the type a function returns, there could be a chance of propagating errors unrelated to the type defined on a function to return. <\/p>\n\n\n\n<p>Luckily, Rust is smart enough to detect these errors during compilation time. Hence, errors like this would not occur when running the code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In conclusion, talking about the <code>?<\/code> operator is talking about error propagation but also writing less code. Why? because the <code>?<\/code> operator is capable of both: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Extracting the value of types such as <code>Result<\/code> and <code>Option<\/code>, allowing developers to not worry extracting or &#8220;unwrapping&#8221; values.<\/li><li>Returning the error type defined in the return type of a function without the need to explicitly use the <code>return<\/code> type and return an error based on the return type of a function.<\/li><\/ul>\n\n\n\n<p><strong>Was this article helpful?<\/strong><\/p>\n\n\n\n<p><strong>I hope this article helped you to clarify doubts and concepts of Rust, especially to those new to the programming language.<\/strong><\/p>\n\n\n\n<p>Share your thoughts by replying on Twitter of <a href=\"https:\/\/twitter.com\/bbprogrammer\" target=\"_blank\" rel=\"noreferrer noopener\">Become A Better Programmer<\/a> or to <a href=\"https:\/\/twitter.com\/arealesramirez\" target=\"_blank\" rel=\"noreferrer noopener\">personal my Twitter account<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-embed aligncenter is-type-rich is-provider-twitter wp-block-embed-twitter\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"twitter-tweet\" data-width=\"550\" data-dnt=\"true\"><p lang=\"en\" dir=\"ltr\">Today, we are excited to say<br><br>println!(&quot;New post announcement!&quot;) in <a href=\"https:\/\/twitter.com\/hashtag\/rustlang?src=hash&amp;ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"noopener\">#rustlang<\/a> <br><br>In this new Rust article we are explaining the meaning of the question mark (?) operator in <a href=\"https:\/\/twitter.com\/hashtag\/Rust?src=hash&amp;ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"noopener\">#Rust<\/a><a href=\"https:\/\/t.co\/ggbEEOZGB7\">https:\/\/t.co\/ggbEEOZGB7<\/a><\/p>&mdash; Become A Better Programmer (@bbprogrammer) <a href=\"https:\/\/twitter.com\/bbprogrammer\/status\/1501562679248531459?ref_src=twsrc%5Etfw\" target=\"_blank\" rel=\"noopener\">March 9, 2022<\/a><\/blockquote><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Have you come across a Rust function that has a question mark (?) and don&#8217;t know what it means? This article explains what the ? does and how you can use it.<\/p>\n","protected":false},"author":1,"featured_media":2319,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[31],"tags":[],"class_list":["post-2311","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-rust","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50"],"_links":{"self":[{"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/posts\/2311","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/comments?post=2311"}],"version-history":[{"count":4,"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/posts\/2311\/revisions"}],"predecessor-version":[{"id":2450,"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/posts\/2311\/revisions\/2450"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/media\/2319"}],"wp:attachment":[{"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/media?parent=2311"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/categories?post=2311"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.becomebetterprogrammer.com\/staging\/4563\/wp-json\/wp\/v2\/tags?post=2311"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}