kinghairstyles.com maphandbook.com

kinghairstyles.com maphandbook.com

 Optional parameters in Rust | KeiruaProd

Je suis développeur web freelance et propose des formations à Symfony2 ! Contactez-moi pour en discuter.

Many languages feature “optional” parameters to function arguments: if you provide a value, it will be used, but if you don’t, a default value will be used instead.

Let’s take a look in python:

def some_function(a = 4):
    print(a * a)

some_function(3)
some_function()

In the previous example, we can provide if we want a to some_function. If we don’t, 4 will be used. some_function will have a value to use for a no matter what

How to do that in Rust? Well, in Rust you have to provide all the parameters a function requests. You can, however, use “Option”s to do two things:

  • make their usage not mandatory
  • provide a default value

The non mandatory behavior is what you are already doing often if you are using Options.

fn optional_value(optional_arg: Option<u32>) {
    if let Some(value) = optional_arg {
        println!("{} = {}", value, value*value);
    }
    else {
        println!("No value is supplied, we won't compute the square");
    }
}

fn main(){        
    optional_value(Some(4));
    optional_value(None);
}

If a value is provided inside optional_arg, we do something out of it, otherwise we do something else like displaying an error message.

Default values are also easy thanks to unwrap_or:

fn default_value(some_param: Option<u32>) {
    let some_param = some_param.unwrap_or(23);
    println!("The optional parameter is {}", some_param);
}

fn main(){
    default_value(Some(4));
    default_value(None);
}

In the defaut_value function, if Some is provided with a value inside, we unwrap and use it, but if None is provided, we replace the content of some_param with a default value using unwrap_or

Another cool trick is to make the parameter a generic over Into<Option<i32>>.

When you do so, you get to call the function with a value (instead of Some(value)) or with None, and then you can

fn optional_with_into<T: Into<Option<i32>>>(value: T) {
    let value = value.into(); // now we have an option
    // then we get to unwrap our option
    match value {
        Some(value) => println!("{} = {}", value, value*value),
        None => println!("No value is supplied, we won't compute the square"),
    }
}

fn main(){
    optional_with_into(4);
    optional_with_into(None);
}

(this is possible because Option itself implements the From trait)

Our course you can also use the unwrap_or in order to provide a default value if None is provided. Don’t forget the call to into !

fn optional_with_default_with_into<T: Into<Option<i32>>>(value: T) {
    let value = value.into().unwrap_or(4);
    // …
}

That being said, the ergonomics for default values is far from perfect.

Répondre