Respuestas:
Cuando concatena cadenas, necesita asignar memoria para almacenar el resultado. Lo más fácil para empezar es String
y &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);
}
Aquí, tenemos una cadena propia que podemos mutar. Esto es eficiente ya que potencialmente nos permite reutilizar la asignación de memoria. Hay un caso similar para String
y String
, como &String
se puede desreferenciar 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);
}
Después de esto, another_owned_string
no se ha tocado (nota sin mut
calificador). Hay otra variante que consume el String
pero no requiere que sea mutable. Esta es una implementación del Add
rasgo que toma a String
como el lado izquierdo y a &str
como el lado derecho:
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);
}
Tenga en cuenta que owned_string
ya no se puede acceder después de la llamada a +
.
¿Qué pasaría si quisiéramos producir una nueva cadena, dejando ambas sin tocar? La forma más simple es 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);
}
Tenga en cuenta que ambas variables de entrada son inmutables, por lo que sabemos que no se tocan. Si quisiéramos hacer lo mismo para cualquier combinación de String
, podemos usar el hecho de que String
también se puede formatear:
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);
}
Sin embargo, no tienes que usar format!
. Puede clonar una cadena y agregar la otra cadena a la nueva cadena:
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 la especificación de tipo que hice es redundante: el compilador puede inferir todos los tipos en juego aquí. ¡Los agregué simplemente para que sean claros para las personas nuevas en Rust, ya que espero que esta pregunta sea popular entre ese grupo!
Add
/ +
símbolo? Podrías cubrirlo si quieres.
.to_owned()
y .to_string()
se ha solucionado desde el comentario anterior gracias a la especialización implícita. Ambos ahora tienen el mismo rendimiento cuando se les llama a &str
. Compromiso
Para concatenar múltiples cadenas en una sola cadena, separadas por otro carácter, hay un par de formas.
Lo mejor que he visto es usar el join
método en una matriz:
fn main() {
let a = "Hello";
let b = "world";
let result = [a, b].join("\n");
print!("{}", result);
}
Dependiendo de su caso de uso, también puede preferir más control:
fn main() {
let a = "Hello";
let b = "world";
let result = format!("{}\n{}", a, b);
print!("{}", result);
}
He visto algunas formas más manuales, algunas evitando una o dos asignaciones aquí y allá. Para propósitos de legibilidad, encuentro que los dos anteriores son suficientes.
join
se une realmente a la SliceContactExt
característica . El rasgo está marcado como inestable, pero sus métodos son estables y están incluidos en el Preludio, por lo que pueden usarse en todas partes de forma predeterminada. El equipo parece ser muy consciente de que este rasgo no necesita existir e imagino que las cosas cambiarán en el futuro con él.
Creo que ese concat
método y +
debería mencionarse aquí también:
assert_eq!(
("My".to_owned() + " " + "string"),
["My", " ", "string"].concat()
);
y también hay concat!
macro pero solo para literales:
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
+
ya se menciona en una respuesta existente . ( Esta es una implementación de la Add
característica que toma String
como el lado de la mano izquierda y una &str
como el lado derecho: )
Hay varios métodos disponibles en RUST para concatenar cadenas
concat!()
):fn main() {
println!("{}", concat!("a", "b"))
}
La salida del código anterior es:
ab
push_str()
y +
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);
}
La salida del código anterior es:
ab
a B C
Using format!()
):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = format!("{}{}", _a, _b);
println!("{}", _c);
}
La salida del código anterior es:
ab
échale un vistazo y experimenta con Rust Play Ground
str
y&str
son diferentes tipos y durante el 99% del tiempo, solo debe preocuparse&str
. Hay otras preguntas que detallan las diferencias entre ellos.