Réponses:
Lorsque vous concaténez des chaînes, vous devez allouer de la mémoire pour stocker le résultat. Le plus simple pour commencer est Stringet &str:
fn main() {
let mut owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
owned_string.push_str(borrowed_string);
println!("{}", owned_string);
}
Ici, nous avons une chaîne possédée que nous pouvons muter. Ceci est efficace car cela nous permet potentiellement de réutiliser l'allocation de mémoire. Il existe un cas similaire pour Stringet String, comme cela &String peut être déréférencé comme&str .
fn main() {
let mut owned_string: String = "hello ".to_owned();
let another_owned_string: String = "world".to_owned();
owned_string.push_str(&another_owned_string);
println!("{}", owned_string);
}
Après cela, another_owned_stringn'est pas touché (notez pas de mutqualificatif). Il existe une autre variante qui consomme le Stringmais ne nécessite pas qu'il soit modifiable. Il s'agit d'une implémentation du Addtrait qui prend a Stringcomme côté gauche et a &strcomme côté droit:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let new_owned_string = owned_string + borrowed_string;
println!("{}", new_owned_string);
}
Notez que ce owned_stringn'est plus accessible après l'appel à +.
Et si nous voulions produire une nouvelle chaîne en laissant les deux intactes? Le moyen le plus simple est d'utiliser format!:
fn main() {
let borrowed_string: &str = "hello ";
let another_borrowed_string: &str = "world";
let together = format!("{}{}", borrowed_string, another_borrowed_string);
println!("{}", together);
}
Notez que les deux variables d'entrée sont immuables, nous savons donc qu'elles ne sont pas touchées. Si nous voulions faire la même chose pour n'importe quelle combinaison de String, nous pouvons utiliser le fait qui Stringpeut également être formaté:
fn main() {
let owned_string: String = "hello ".to_owned();
let another_owned_string: String = "world".to_owned();
let together = format!("{}{}", owned_string, another_owned_string);
println!("{}", together);
}
Vous n'êtes pas obligé de l'utiliser format!. Vous pouvez cloner une chaîne et ajouter l'autre chaîne à la nouvelle chaîne:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let together = owned_string.clone() + borrowed_string;
println!("{}", together);
}
Remarque - toute la spécification de type que j'ai faite est redondante - le compilateur peut déduire tous les types en jeu ici. Je les ai ajoutés simplement pour être clair pour les nouveaux utilisateurs de Rust, car je m'attends à ce que cette question soit populaire auprès de ce groupe!
Add/ +symbol? Vous pouvez le couvrir si vous le souhaitez.
.to_owned()et .to_string()a été corrigé depuis le commentaire ci-dessus grâce à la spécialisation impl. Ils ont tous deux maintenant les mêmes performances lorsqu'ils sont appelés sur un &str. Commit pertinent: github.com/rust-lang/rust/pull/32586/files
Pour concaténer plusieurs chaînes en une seule chaîne, séparées par un autre caractère, il existe plusieurs méthodes.
Le plus beau que j'ai vu utilise la joinméthode sur un tableau:
fn main() {
let a = "Hello";
let b = "world";
let result = [a, b].join("\n");
print!("{}", result);
}
En fonction de votre cas d'utilisation, vous pouvez également préférer plus de contrôle:
fn main() {
let a = "Hello";
let b = "world";
let result = format!("{}\n{}", a, b);
print!("{}", result);
}
J'ai vu d'autres méthodes manuelles, certaines évitant une ou deux allocations ici et là. Pour des raisons de lisibilité, je trouve les deux ci-dessus suffisants.
joinest réellement attaché à la SliceContactExttrait . Le trait est marqué comme instable mais ses méthodes sont stables et sont incluses dans le Prelude donc elles sont utilisables partout par défaut. L'équipe semble bien consciente que ce trait n'a pas besoin d'exister et j'imagine que les choses vont changer à l'avenir avec lui.
Je pense que cette concatméthode et +devrait être mentionnée ici aussi:
assert_eq!(
("My".to_owned() + " " + "string"),
["My", " ", "string"].concat()
);
et il y a aussi concat!macro mais uniquement pour les littéraux:
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
+est déjà mentionné dans une réponse existante . ( Ceci est une mise en œuvre du Addtrait qui prend Stringcomme côté gauche et &strque la droite: )
Il existe différentes méthodes disponibles dans RUST pour concaténer des chaînes
concat!()):fn main() {
println!("{}", concat!("a", "b"))
}
La sortie du code ci-dessus est:
un B
push_str()et +opérateur):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = "c".to_string();
_a.push_str(&_b);
println!("{}", _a);
println!("{}", _a + &_b);
}
La sortie du code ci-dessus est:
un B
abc
Using format!()):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = format!("{}{}", _a, _b);
println!("{}", _c);
}
La sortie du code ci-dessus est:
un B
Découvrez-le et expérimentez avec le terrain de jeu Rust
stret&strsont de types différents et pour 99% du temps, vous ne devriez vous en soucier que&str. Il y a d'autres questions détaillant les différences entre elles.