J'essaie d'implémenter une fonction qui lit les arguments de ligne de commande et les compare aux littéraux de chaîne codés en dur.
Lorsque je fais la comparaison avec une instruction if
, cela fonctionne comme un charme:
fn main() {
let s = String::from("holla!");
if s == "holla!" {
println!("it worked!");
}
}
Mais en utilisant une instruction match
(qui, je suppose, serait plus élégante):
fn main() {
let s = String::from("holla!");
match s {
"holla!" => println!("it worked!"),
_ => println!("nothing"),
}
}
Je reçois toujours une erreur du compilateur qu'un String
était attendu mais un &static str
a été trouvé:
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`
J'ai vu Comment faire correspondre une chaîne avec des littéraux de chaîne dans Rust? donc je sais comment le réparer, mais je veux savoir pourquoi la comparaison fonctionne lorsque if
mais sans utiliser match
.
Je veux savoir pourquoi la comparaison fonctionne lorsque
if
mais sans utilisermatch
.
Il ne s'agit pas tant de if
et plus parce que vous avez utilisé ==
dans l'état. La condition dans une instruction if
est toute expression de type bool
; il se trouve que vous avez choisi d'utiliser ==
Là.
Le ==
L'opérateur est vraiment une fonction associée à le trait PartialEq
. Ce trait peut être implémenté pour n'importe quelle paire de types. Et, pour plus de commodité, String
a des implémentations pour PartialEq<str>
et PartialEq<&str>
, entre autres - et vice versa.
D'un autre côté, les expressions match
utilisent correspondance de modèle pour la comparaison, pas ==
. UNE &'static str
littéral, comme "holla!"
, est un modèle valide, mais il ne peut jamais correspondre à un String
, qui est un type complètement différent.
La correspondance de motifs vous permet de comparer de manière concise des parties de structures complexes, même si le tout n'est pas égal, ainsi que de lier des variables à des parties de la correspondance. Bien que String
s n'en bénéficient pas vraiment, il est très puissant pour d'autres types et a un objectif entièrement différent de ==
.
Notez que vous pouvez utiliser la correspondance de motifs avec if
en utilisant à la place if let
construire. Votre exemple ressemblerait à ceci:
if let "holla!" = &*s {
println!("it worked!");
}
Inversement, une façon d'utiliser ==
à l'intérieur d'un match
est comme ceci:
match s {
_ if s == "holla!" => println!("it worked!"),
_ => println!("nothing"),
}
Ou, comme l'a suggéré @ljedrz:
match s == "holla!" {
true => println!("it worked!"),
_ => println!("nothing")
}