web-dev-qa-db-fra.com

Comment concaténer des chaînes?

Comment concaténer les combinaisons de types suivantes:

  • str et str
  • String et str
  • String et String
125
jsalter

Lorsque vous concaténez des chaînes, vous devez allouer de la mémoire pour stocker le résultat. Le plus simple est String et _&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 appartenant à laquelle nous pouvons muter. C'est efficace car cela nous permet potentiellement de réutiliser l'allocation de mémoire. Il existe un cas similaire pour String et String, sous la forme _&String_ peut être déréférencé sous la forme _&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);
}
_

Ensuite, _another_owned_string_ n'est plus modifié (notez le qualificatif mut). Il existe une autre variante qui consomme le String mais ne nécessite pas sa mutabilité. Ceci est un implémentation du trait Add qui prend un String comme côté gauche et un _&str_ comme 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 _owned_string_ n'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 consiste à 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 toute combinaison de String, nous pouvons utiliser le fait que String peut é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'avez pas pour utiliser _format!_ bien que. 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 simplement ajoutées pour que les nouveaux venus dans Rust soient clairs, car je m'attends à ce que cette question soit populaire auprès de ce groupe!

162
Shepmaster

Pour concaténer plusieurs chaînes en une seule chaîne, séparées par un autre caractère, il existe deux manières.

Le plus gentil que j'ai vu utilise la méthode join 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 préférerez peut-être davantage 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 attributions ici et là. Pour des raisons de lisibilité, j'estime que les deux précédents sont suffisants.

32
Simon Whitehead

Je pense que la méthode concat et _+_ devrait également être mentionnée ici:

_assert_eq!(
  ("My".to_owned() + " " + "string"),
  ["My", " ", "string"].concat()
);
_

et il y a aussi concat! macro mais seulement pour les littéraux:

_let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
_
3
suside