55

I forgot to specify the type of a parameter and the error message was as follows:

error: expected one of `:` or `@`, found `)`
 --> src/main.rs:2:12
  |
2 | fn func(arg)
  |            ^ expected one of `:` or `@` here

Which raises the question: what can you do with an @ symbol? I don't remember reading about using the @ symbol for anything. I also did some Googling and couldn't find anything. What does @ do?

2

2 Answers 2

52

You can use the @ symbol to bind a pattern to a name. As the Rust Reference demonstrates:

let x = 1;

match x {
    e @ 1 ... 5 => println!("got a range element {}", e),
    _ => println!("anything"),
}

Assignments in Rust allow pattern expressions (provided they are complete) and argument lists are no exception. In the specific case of @, this isn't very useful because you can already name the matched parameter. However, for completeness, here is an example which compiles:

enum MyEnum {
    TheOnlyCase(u8),
}

fn my_fn(x @ MyEnum::TheOnlyCase(_): MyEnum) {}
Sign up to request clarification or add additional context in comments.

3 Comments

When I read the docs, I think it finally clicked for me – but would I be correct in saying that pattern binding with @ is shorthand for guards? E.g., e if 1 <= e && e <= 5? Not saying the shorthand wouldn't be helpful / possibly make the source clearer (assuming the syntax is understood) – I just want to make sure I'm not missing a use case of @ in the spirit of "what can you do with the @ symbol".
@SeanAllred That's certainly one way to look at it. In the examples I gave, you'd basically be correct. The only thing I'd mention is that patterns can be nested and @ let's you bind different parts of a structure to various names: a @ Some(p @ Point { x = 5, .. }) now a has type Option<Point> and p has type Point.
wow. I just found out about this again. And few weeks ago I needed this knowledge. Been coding for around 4 years in Rust now. I liked this SO post before but failed to remember this.
2

The @ symbol allows you to reuse a variable holding a value that's used simultaneously in a match pattern.

For example:

enum Student {
    Junior{ id: u32}
}

let me = Student::Junior{ id: 10 };

match me {
    Student::Junior{ id: id_val @ 0..=10 } => println!("in range with id: {}", id_val),
    Student::Junior{ id: 11..=20 } => println!("in range 11->20"),
    Student::Junior{ id } => println!("outside range with id: {}", id)
}

In this example, by binding id to the id_val the match can be used in the println!(), otherwise this won't be possible as seen in the second match expression.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.