Pattern Matching

Is there any technical differences between match and if when checking things. Consider this:

...
let resp = match some_async_fn(arg).await {
    ...
    //arms here
    ...
}
...

and this:

...
let resp = some_async_fn(arg).await;
let val = match resp {
    ...
    //arms here
    ...
}
...

Does matching directly into .await call has certain overhead over matching the returned value?

There's no overhead. match expects an expression, so either storing it in a variable or matching directly on it works the same.

There is generally no overhead, however, in certain cases the ordering of freeing resources may be different:

struct BigResource { /* … */ }

impl Drop for BigResource {
    fn drop(&mut self) {
        println!("BigResource has been released")
    }
}

struct Foo {
    number: i32,
    #[allow(dead_code)]
    big: BigResource,
}

async fn some_async_fn(arg: i32) -> Foo {
    Foo {
        number: arg + 1,
        big: BigResource { /* … */ },
    }
}

async fn foo() {
    let resp = some_async_fn(7).await;
    let val = match resp {
        Foo { number, .. } => {
            println!("Doing some work here");
            number
        }
    };
    println!("Doing more work here");
    println!("Result: {}", val);
}

async fn bar() {
    let val = match some_async_fn(7).await {
        Foo { number, .. } => {
            println!("Doing some work here");
            number
        }
    };
    println!("Doing more work here");
    println!("Result: {}", val);
}

#[tokio::main]
async fn main() {
    foo().await;
    println!("------------");
    bar().await;
}

(Playground)

Output:

Doing some work here
Doing more work here
Result: 8
BigResource has been released
------------
Doing some work here
BigResource has been released
Doing more work here
Result: 8

If that is an issue, you could also drop manually.


I think the corresponding section of the reference is "Temporary Scopes" in "Drop Scopes" in "Destructors". Difficult to read though (for me).

2 Likes

This article has a fairly thorough walkthrough of how this difference can cause bugs in real code

What kind of overhead would you expect and why?

great explanation, thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.