Respostas:
Ao concatenar cadeias, você precisa alocar memória para armazenar o resultado. O mais fácil de começar é String
e &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);
}
Aqui, temos uma string de propriedade que podemos mudar. Isso é eficiente, pois potencialmente nos permite reutilizar a alocação de memória. Há um caso semelhante para String
e String
, como &String
pode ser desreferenciado como&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);
}
Depois disso, another_owned_string
fica intocado (observe o mut
qualificador). Há outra variante que consome o String
mas não exige que seja mutável. Esta é uma implementação da Add
característica que leva a String
como lado esquerdo e a &str
como lado direito:
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);
}
Observe que owned_string
não é mais acessível após a chamada para +
.
E se quiséssemos produzir uma nova string, deixando as duas intocadas? A maneira mais simples é usar format!
:
fn main() {
let borrowed_string: &str = "hello ";
let another_borrowed_string: &str = "world";
let together = format!("{}{}", borrowed_string, another_borrowed_string);
println!("{}", together);
}
Observe que as duas variáveis de entrada são imutáveis; portanto, sabemos que elas não são tocadas. Se quisermos fazer o mesmo para qualquer combinação de String
, podemos usar o fato de que String
também pode ser formatado:
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);
}
Você não precisa usar isso format!
. Você pode clonar uma sequência e anexá-la à nova sequência:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let together = owned_string.clone() + borrowed_string;
println!("{}", together);
}
Nota - toda a especificação de tipo que fiz é redundante - o compilador pode inferir todos os tipos em jogo aqui. Eu os adicionei simplesmente para ficar claro para as pessoas novas no Rust, pois espero que essa pergunta seja popular com esse grupo!
Add
/ +
símbolo? Você pode cobrir se quiser.
.to_owned()
e .to_string()
foi corrigida desde o comentário acima, graças à especialização impl. Ambos agora têm o mesmo desempenho quando chamados a &str
. Confirmação
Para concatenar várias cadeias de caracteres em uma única cadeia, separadas por outro caractere, há duas maneiras.
O mais legal que eu já vi é usar o join
método em uma matriz:
fn main() {
let a = "Hello";
let b = "world";
let result = [a, b].join("\n");
print!("{}", result);
}
Dependendo do seu caso de uso, você também pode preferir mais controle:
fn main() {
let a = "Hello";
let b = "world";
let result = format!("{}\n{}", a, b);
print!("{}", result);
}
Existem algumas maneiras mais manuais que eu já vi, algumas evitando uma ou duas alocações aqui e ali. Para fins de legibilidade, acho que os dois acima são suficientes.
join
está realmente ligado à SliceContactExt
característica . A característica é marcada como instável, mas seus métodos são estáveis e estão incluídos no Prelude, para que possam ser usados em qualquer lugar por padrão. A equipe parece estar ciente de que essa característica não precisa existir e eu imagino que as coisas mudarão no futuro com ela.
Eu acho que esse concat
método e +
deve ser mencionado aqui também:
assert_eq!(
("My".to_owned() + " " + "string"),
["My", " ", "string"].concat()
);
e também há concat!
macro, mas apenas para literais:
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
+
já foi mencionado em uma resposta existente . ( Esta é uma implementação do Add
traço que leva a String
que o lado esquerdo e um &str
como o lado direito: )
Existem vários métodos disponíveis no RUST para concatenar seqüências de caracteres
concat!()
):fn main() {
println!("{}", concat!("a", "b"))
}
A saída do código acima é:
ab
push_str()
e +
operador):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);
}
A saída do código acima é:
ab
abc
Using format!()
):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = format!("{}{}", _a, _b);
println!("{}", _c);
}
A saída do código acima é:
ab
confira e experimente o Rust play ground
str
e&str
são tipos diferentes e, por 99% do tempo, você só deve se preocupar&str
. Há outras perguntas detalhando as diferenças entre eles.