Start learning free

LESSON 39 OF 414 · FUNCTIONS I

Fixing an Ignored Parameter in Rust

Practice Read the full explanation

Inside the code editor we've tried to write a function that takes a person's name as argument and prints a tailored welcome message for that person.

Then, we welcomed Andy and John by calling the function for each of them.

So when we ran the code, we expected it to print:

Welcome, Andy!
Welcome, John!

but it seems like we made some mistakes because when we run our code, it prints:

Welcome, Andy!
Welcome, Andy!

Assignment:

Your task is to fix our code such that no errors will be produced and it will print the desired output.

STEP 1 OF 1
    Ctrl + Enter to check

    RUST · FUNCTIONS I

    Buggy Code 5 in Rust, explained

    What the code is supposed to do

    The function welcome_user takes a name and should print a welcome message for that person. The program calls it for Andy and then for John, so the expected output is:

    Welcome, Andy!
    Welcome, John!
    

    Instead, both lines say Andy:

    Welcome, Andy!
    Welcome, Andy!
    
    fn welcome_user(name: String) {
        println!("Welcome, Andy!");
    }
    fn mainFunction() {
        welcome_user("Andy".to_string());
        welcome_user("John".to_string());
    }
    

    What goes wrong

    The calls are correct. The first passes "Andy", the second passes "John", and both are converted to the owned String that the parameter expects. The bug is inside the function. The body prints the fixed text Welcome, Andy! and never looks at name.

    A parameter does nothing by itself. It is a variable that holds the argument, and it affects the output only if the body uses it. Here the value "John" arrives in the function and is silently dropped at the end of the call.

    The compiler hints at this. It still builds the program, but warns that name is an unused variable and suggests naming it _name if that is intentional. A warning does not stop the build, which is why this bug reaches run time and shows up as wrong output instead of an error.

    Fixing it step by step

    1. Find what changes between calls. Only the name should differ, so the name must come from the parameter.
    2. Replace the hard-coded name with a placeholder. In the format string, Andy becomes {}.
    3. Pass the parameter after the format string. println! fills each {} with the next argument, so add , name.
    4. Leave the calls alone. They already pass the right values.

    The fixed code in Rust

    fn welcome_user(name: String) {
        println!("Welcome, {}!", name);
    }
    fn mainFunction() {
        welcome_user("Andy".to_string());
        welcome_user("John".to_string());
    }
    
    /* Explanation:
    
    Notice that in the original function we didn't actually use our parameter "name".
    
    And so the function printed "Welcome, Andy!" no matter if we passed "Mike" or "Sally" etc. to it.
    
    The fix is to use the parameter "name" with string concatenation or string formatting to dynamically construct the message:
    println!("Welcome, {}!", name);
    
    */
    

    Some details about println! that matter here:

    • The format string is a literal. It must be written directly in the macro call. You cannot build the message by gluing a variable onto a string with + inside println!.
    • Placeholders are filled in order. The first {} takes the first argument after the string, the second {} takes the second, and so on. The number of placeholders must equal the number of arguments, or the program does not compile.
    • Newer Rust also accepts {name}. A variable name inside the braces is read from the surrounding scope, so println!("Welcome, {name}!") prints the same text. The lesson uses the {} form.

    Why this bug is easy to miss

    The program compiles, runs and prints a perfectly valid sentence, so nothing crashes. The only sign is that the output differs from what you meant. When a function gives the same result for different arguments, check whether its parameters are used at all. A good habit is to trace one call by hand: with name equal to "John", which line of the body mentions John? If none does, the parameter is being ignored.

    Common mistakes

    • Changing the calls instead of the function. Editing the arguments does nothing, because the body ignores them.
    • Typing the placeholder but no argument. println!("Welcome, {}!"); fails to compile with an error about a missing argument.
    • Dropping the punctuation. The output must match exactly: the comma after Welcome, the space, and the ! at the end.
    • Silencing the warning with _name. That removes the warning but not the bug. The fix is to use the value, not to hide that it is unused.

    Checking your fix

    Run the code in the editor above. After the fix, welcome_user("Andy".to_string()) prints Welcome, Andy! and welcome_user("John".to_string()) prints Welcome, John!. Any other name passed in would appear in its own message in the same way.

    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free