Why can I compare a String to a &str using if, but not when using match?
I want to know why the comparison works when
if
but not usingmatch
.
It's not so much about if
and more because you've used ==
in the condition. The condition in an if
statement is any expression of type bool
; you just happen to have chosen to use ==
there.
The ==
operator is really a function associated with the PartialEq
trait. This trait can be implemented for any pair of types. And, for convenience, String
has implementations for PartialEq<str>
and PartialEq<&str>
, among others - and vice versa.
On the other hand, match
expressions use pattern matching for comparison, not ==
. A &'static str
literal, like "holla!"
, is a valid pattern, but it can never match a String
, which is a completely different type.
Pattern matching lets you concisely compare parts of complex structures, even if the whole thing isn't equal, as well as bind variables to pieces of the match. While String
s don't really benefit from that, it's very powerful for other types, and has an entirely different purpose than ==
.
Note that you can use pattern matching with if
by instead using the if let
construct. Your example would look like this:
if let "holla!" = &*s {
println!("it worked!");
}
Conversely, one way to use ==
inside a match
is like this:
match s {
_ if s == "holla!" => println!("it worked!"),
_ => println!("nothing"),
}
Or, as @ljedrz suggested:
match s == "holla!" {
true => println!("it worked!"),
_ => println!("nothing")
}
As @peter-hall said, there's a mismatch of types because match
expressions use pattern matching, which is different from the ==
that are associated with the PartialEq
trait.
There a second way to resolve this issue, by casting your String
into an &str
(a string slice) :
match &s[..] {
"holla!" => println!("it worked!"),
"Hallo!" => println!("with easy to read matches !"),
_ => println!("nothing"),
}