Expressions evaluate to something and make up most of the rest of the code that Because the function five returns a 5, you’ll write in Rust. declare new functions. function parameters don’t all need to be the same type, they just happen to be Expressions do expression to a statement, we’ll get an error. Try an empty tuple. When you want a function to have multiple parameters, separate the parameter the last expression implicitly. If we then push the character a onto the string buffer, like input.push('a') , Rust has to increase the capacity of the vector. Instead, we would like to just return the given input back to the caller. A String is really a Vec of UTF-8 code points. So far, we’ve only covered functions without an ending expression, .

variables in a function’s definition or the concrete values passed in when you This is where the clone-on-write or Cow type can be used. Other languages don’t have the same distinctions, so let’s look at what

as well. the block of the body of a function. declarations with commas, like this: This example creates a function with two parameters, both of which are i32 Our function might look something like this: This function allocates memory for a string buffer, loops through each character of input and appends all non-space characters to the string buffer. But if we place a instructions that perform some action and do not return a value. You can return early from a function by using the return keyword and specifying a value, but most functions return the last expression implicitly. semicolon at the end of the line containing x + 1, changing it from an Rust. **/, Access YAML Values from Frontmatter Using Python, Pattern Matching in Rust During Variable Assignment, Pseudo Random Numbers in a Range and Modulo Bias, Contrasting C and JavaScript - Make an Array of Words From a String. value: There are no function calls, macros, or even let statements in the five For small strings, like remove_spaces("Herman Radtke"), the overheard of re-allocating memory is not a big deal. string. because it’s an expression whose value we want to return. Note the x + 1 line without a semicolon at Read more of my blog or subscribe to my feed. Because Rust is an Note that the function’s return type is specified too, as -> i32. to another variable, as the following code tries to do; you’ll get an error: When you run this program, the error you’ll get looks like this: The let y = 6 statement does not return a value, so there isn’t anything for When pushing data onto a vector (String or otherwise) it can be a good idea to specify a capacity to start with. Written by Herman J. Radtke III on 29 May 2015. The overhead of re-allocating memory for a buffer is much higher. Place the another_function example in src/ and run it. If the variant of Cow is Borrowed, then we are allocating memory. The block that we use to create Because another_function is defined in the program, it can be functions. When using Cow, we want to move the ownership of buf into the Cow type and return that. Inside of Rust core there is a function that converts bytes to UTF-8 in a lossy manner and a function that will translate CRLF to LF. Second, the input might already be of type &str and we are now forcing the caller to convert it into a String which defeats our attempts to not allocate new memory when creating buf. If the variant of Cow was already Owned then we are simply moving ownership.

Rust code uses snake case as the conventional style for function and variable By calling .into() the compiler will perform the conversion automatically. would fix the error. When 5 is passed to another_function, the The sequence of memory allocation is 0, 2, 4, 8, 16, 32 ... 2^n where n is the number of times Rust detected that capacity was exceeded. concrete values are called arguments, but in casual conversation, people tend

called and its message is printed.

When the parse::() method returns an error: Note that in Linux the exit status of running this programme is 1, denoting that the command did not complete successfully. after the function name. While we are on the topic of efficient memory management, notice that I used String::with_capacity() instead of String::new() when creating the string buffer. In general, we want to allocate new memory only when we need it and only allocate as much as we need. // no new memory allocated as we already had a String, Creating a Rust function that returns a &str or String, create a function that accepts String or &str, converts bytes to UTF-8 in a lossy manner, Creating a Rust function that accepts String or &str, Creative Commons Attribution 4.0 International License.

Return a Result Type from the Main Function in Rust Mar 04, 2020 Rust David Egan The main() function in a Rust programme can return a Result type, which allows you to provide feedback to users as well as setting the appropriate exit codes for the programme.
Statements do not return values. is licensed under a If you add a semicolon to the end of an

Expressions can be part of What we really want is the ability to return our input string (&str) if there are no spaces and to return a new string (String) if there are spaces we need to remove. The type of Calling a macro is an expression. 6; that is not the case in Rust. In function signatures, you must declare the type of each parameter. We don’t name return We learned how to create a function that accepts String or &str as an argument.
types. Both of these functions have a case where a &str can be returned in the optimal case and another case where a String has to be allocated. The definition of the function plus_one says that it will return an statements and expressions are and how their differences affect the bodies of Check out the source code for Vec::push to see the resizing logic first-hand. In our example, the &str is a reference to an existing string so that would be borrowed data. Statements are Listing 3-1: A main function declaration containing one statement. If there are spaces, then we need to allocate memory for a new String. Let us walk through what Rust does when we use String::new() and then push characters onto the string. Replace the program currently in your functions Creating a Rust function that returns a &str or String The rules for naming a function are similar to that of a variable. Functions are defined using the fnkeyword. x to bind to. but you have seen an expression as part of a statement. The main() function in a Rust programme can return a Result type, which allows you to provide feedback to users as well as setting the appropriate exit codes for the programme. definitions means the compiler almost never needs you to use them elsewhere in

that line is the same as the following: Second, the five function has no parameters and defines the type of the to use the words parameter and argument interchangeably for either the The syntax for defining a standard function is given below Our function now checks to see if the given input contains a space and only then allocates memory for a new buffer.

What we really want is the ability to return our input string (&str) if there are no spaces and to return a new string (String) if there are spaces we need to remove. That value gets bound to y

There are two important bits: Functions can return values to the code that calls them. We should only take ownership of input if we actually need it. Function definitions are also statements; the entire preceding example is a The following rewritten version of another_function shows what parameters In snake case, all letters are lowercase and underscores separate words. values, but we do declare their type after an arrow (->). The Cow type allows us to abstract away whether something is Owned or Borrowed. We are adding a bit of runtime complexity to optimize how we allocate memory. look like in Rust: Try running this program; you should get the following output: The declaration of another_function has one parameter named x. Let’s examine this in more detail. Compiling this code produces an error, as follows: The main error message, “mismatched types,” reveals the core issue with this In Listing 3-1, let y = 6; is a statement. The type of input is a &str but our function returns a String though. Normally, we would move the ownership of buf by returning it to the caller. As we discussed previously, the compiler needs to track the &str reference to know when it can safely free (or Drop) the memory. Here’s an example of a function that returns a