Reputation: 7881
This is one of those simple-but-I-don't-know-how-to-do-it-in-rust things.
Simply put:
pub fn pair_matcher(tup: &(String, String)) {
match tup {
&("foo".as_string(), "bar".as_string()) => print!("foobar"),
_ => print!("Unknown"),
}
}
I get the error
-:3:17: 3:18 error: expected `,`, found `.`
-:3 &("foo".as_string(),"bar".as_string())=> { print!("foobar"); }
^
How do you match this?
Upvotes: 3
Views: 4252
Reputation: 90742
The left hand side of each branch of a match is not an expression, it is a pattern, which restricts what can go there to basically just literals (plus things like ref
which change the binding behaviour); function calls are right out. Given how String
works, it’s not possible to get one of them into a pattern (because you can’t construct one statically). It could be achieved with if
statements:
if tup == ("foo".to_string(), "bar".to_string()) {
print!("foobar")
} else {
print!("Unknown")
}
… or by taking a slice of the String
s, yielding the type &str
which can be constructed literally:
match (tup.0.as_slice(), tup.1.as_slice()) {
("foo", "bar") => print!("foobar"),
_ => print!("Unknown"),
}
Constructing a new String
each time is an expensive way of doing things, while using the slices is pretty much free, entailing no allocations.
Note that the .0
and .1
requires #![feature(tuple_indexing)]
on the crate; one can do without it thus:
let (ref a, ref b) = tup;
match (a.as_slice(), b.as_slice()) {
("foo", "bar") => print!("foobar"),
_ => print!("Unknown"),
}
Because, you see, the left hand side of a let
statement is a pattern as well, and so you can pull the tuple apart with it, taking references to each element, with (ref a, ref b)
yielding variables a
and b
both of type &String
.
The Patterns section of the guide goes into some more detail on the subject.
Upvotes: 4
Reputation: 7881
The solution here is that you need to cast types in the other direction:
match (tup.0.as_slice(), tup.1.as_slice()) {
("foo", "bar") => print!("foobar"),
}
Upvotes: 1