Difference between match and unwrap_or when defining types

The following is a valid file that I can compile with Rust 1.23.0:

fn main() {
    let r = String::from("a");
    let a = Some(&r);
    let b = match a {
        Some(name) => name,
        None => "",
    };
    println!("{}", b);
}

While the following code

fn main() {
    let r = String::from("a");
    let a = Some(&r);
    let b = a.unwrap_or("");
    println!("{}", b);
}

Error with error:

error[E0308]: mismatched types
 --> src/main.rs:4:25
  |
4 |     let b = a.unwrap_or("");
  |                         ^^ expected struct `std::string::String`, found str
  |
  = note: expected type `&std::string::String`
             found type `&'static str`

As far as I understand, the reasoning for compilers when defining types is as follows:

  • In the case of, matchhe determines what bis &str, as he None => ""is &str, and Some(name) => nameis &String, therefore he can become &str.

  • In the case where the argument unwrap_oris &str, instead of entering bin quality &str, it sees there the difference between the type contained in a(namely &String) and the type of the parameter unwrap_or.

What is the difference between the two cases that make type inference this way?

unwrap_or, , , , , , ?

, unwrap_or String , ?

, - , :

let b = a.map(|s| s.as_ref()).unwrap_or("")

, match, , , match , .

+4
1

, .

a Option<&String>. &String &str, &str &String. :

fn main() {
    let a = String::from("This is a String");
    let a_r = &a;
    foo(a_r);
    bar(a_r);

    let b = "This is an &str";
    // Next line will cause a compilation error if uncommented
    // foo(b);
    bar(b);
}

fn foo(s: &String) {
    println!("Foo: {}", s);
}

fn bar(s: &str) {
    println!("Bar: {}", s);
}

foo(b); , , String, str.

match &str ( &String), unwrap_or , Option, &String, &str (String::from, to_string, to_owned ..)

, , , .


("foo") , . - &str, str. , , . , , , - - ("fooquxegg") - , , .

A String, , . , String, "", , - " " - , String , , Box<T> T .

, &String &str ( -, - , ), &str &String. (, "foo"), , , &String, , (, "bar"), - .


:

fn main() {
   let s = "this is an &str";
   let b = String::from("this is a String");
   let s_o : Option<&str> = Some(s);

   let s_or_def = s_o.unwrap_or(&b);
   println!("{}", s_or_def);
}

unwrap_or: A Option<&str>, &String . , &String => &str , , . , , unwrap_or , ; , T ( T &str).

, unwrap_or , &str &String, , unwrap_or . , , unwrap_or String. to_string , :

fn main() {
    let s = String::from("Hello, world!");
    let o = Some(s);
    let r = o.unwrap_or("Goodbye, world!".to_string());

    println!("{}", r);
}

map_or, , |s| &s ( ).

+2

Source: https://habr.com/ru/post/1695137/


All Articles