コマンドライン引数を読み取り、ハードコードされた文字列リテラルと比較する関数を実装しようとしています。
if
ステートメントとの比較を行うと、魅力的に機能します。
fn main() {
let s = String::from("holla!");
if s == "holla!" {
println!("it worked!");
}
}
しかし、match
ステートメントを使用すると(よりエレガントになると思います):
fn main() {
let s = String::from("holla!");
match s {
"holla!" => println!("it worked!"),
_ => println!("nothing"),
}
}
String
が予期されていたが&static str
発見された:
error[E0308]: mismatched types
--> src/main.rs:5:9
|
5 | "holla!" => println!("it worked!"),
| ^^^^^^^^ expected struct `std::string::String`, found reference
|
= note: expected type `std::string::String`
found type `&'static str`
私は Rustで文字列を文字列リテラルと照合する方法? を見たので、それを修正する方法を知っていますが、知りたいですなぜif
を使用しても、match
を使用しない場合、比較は機能します。
if
を使用しても、match
を使用しない場合に比較が機能する理由を知りたいです。
条件で==
を使用したため、if
などについてはそれほど重要ではありません。 if
ステートメントの条件は、bool
型の式です。あなたはたまたまそこで==
を使用することを選択したのです。
==
演算子は、実際には PartialEq
特性 に関連付けられた関数です。この特性は、任意のpairタイプに実装できます。そして、便宜上、String
にはPartialEq<str>
とPartialEq<&str>
の実装があり、その逆も同様です。
一方、match
式では、比較のために==
ではなく パターンマッチング を使用します。 &'static str
のような"holla!"
リテラルは有効なパターンですが、完全に異なる型であるString
と一致することはありません。
パターンマッチングを使用すると、全体が等しくなくても、複雑な構造の部分を簡潔に比較したり、変数を一致の一部にバインドしたりできます。 String
sは実際にはメリットがありませんが、他の型に対しては非常に強力であり、==
とはまったく異なる目的を持っています。
if let
構文を使用する代わりに、if
でパターンマッチングを使用できることに注意してください。あなたの例は次のようになります:
if let "holla!" = &*s {
println!("it worked!");
}
逆に、match
内で==
を使用する1つの方法は次のとおりです。
match s {
_ if s == "holla!" => println!("it worked!"),
_ => println!("nothing"),
}
または、@ ljedrzが示唆したように:
match s == "holla!" {
true => println!("it worked!"),
_ => println!("nothing")
}