The code is taken from the translation of The Rust Programming Language, section Templates .

struct Person { name: Option<String>, } let name = "Steve".to_string(); let mut x: Option<Person> = Some(Person { name: Some(name) }); match x { Some(Person { name: ref a @ Some(_), .. }) => println!("{:?}", a), _ => {} } 

I do not understand where Some came from and what it all is. Maybe I missed something and now I do not understand. Explain what it is and how useful such a construct is in this code. Person structure, but why do we put it in Some?

2 answers 2

Some is an Option type constructor. We use it in pattern matching ( match ). If x is Some , the println!("{:?}", a), Branch,) will be executed. This is similar to a switch , but the choice of a variant is made not by a numerical value, but by whether it is in Option - Some<T> or None .

The structure we put in Some to indicate that the structure may be missing. Because structures are stored in Rust by value, once a value of type Person declared and initialized, it is guaranteed to exist. Option<Person> indicates that Person may or may not be.

    I answer the question "where did Some come from". Option type is declared like this:

     enum Option<T> { Some(T), None, } 

    That is, it denotes a nulllable type (maybe or maybe not), the type-safe replacement is NULL. NULL in C can replace any type, so that when it is transmitted, the original type is lost, and None is always associated with some kind of original type.

    In the safe code in Raste, NULL cannot be passed, so if any parameter or variable may be missing, this fact is declared to the compiler explicitly via the type Option.

    In a normal situation, accessing variants of enum comes with qualifications, that is, you can write this: Option::Some(T) , Option::None . However, the Option type is so often used that in the standard prelude, std :: prelude, use Option::*; is done use Option::*; , which makes options of this type Some and None available without full qualifications.

    • Another enum-type, variants of which are imported in the prelude enum Result<T, E> { Ok(T), Err(E), } (used in situations where you need to return either a value or an error, ideologically replaces exceptions), therefore everywhere they write simply Ok and Err instead of Result :: Ok and Result :: Err. If you want to address your own enum directly, you can also use MyEnum::*; but it is not recommended because litters the namespace. Result and Option in a special position, because actually system and used everywhere. - kstep