String es el búfer de cadena UTF-8 estándar:
fn main() {
let mut s1 = String::new();
s1.push_str("Hello");
println!("s1: len = {}, capacity = {}", s1.len(), s1.capacity());
let mut s2 = String::with_capacity(s1.len() + 1);
s2.push_str(&s1);
s2.push('!');
println!("s2: len = {}, capacity = {}", s2.len(), s2.capacity());
let s3 = String::from("🇨🇭");
println!("s3: len = {}, number of chars = {}", s3.len(),
s3.chars().count());
}
Si ejecutamos este código:
Compiling hello_cargo v0.1.0
Finished dev [unoptimized + debuginfo] target(s) in 0.65s
Running `target/debug/hello_cargo`
s1: len = 5, capacity = 8
s2: len = 6, capacity = 6
s3: len = 8, number of chars = 2
String implementa Deref<Target = str>, lo que significa que puedes llamar a todos los métodos str en un String.
- String::new devuelve una nueva cadena vacía, se usa String::with_capacity cuando se sabe cuántos caracteres tiene la cadena.
- String::len devuelve el tamaño de la cadena en bytes (que puede ser diferente de su longitud en caracteres).
- String::chars devuelve un iterador sobre los caracteres reales. Un carácter puede ser diferente de lo que un humano considerará un "carácter" debido a los grupos de grafemas.
- Cuando las personas se refieren a cadenas, podrían estar hablando de &str o String.
- Cuando un tipo implementa Deref<Target = T>, el compilador le permitirá llamar de forma transparente a métodos desde T.
- String implementa Deref<Target = str> que le da acceso de forma transparente a los métodos de str.
- String se implementa como un contenedor alrededor de un vector de bytes; muchas de las operaciones que ve admitidas en vectores también se admiten en String, pero con algunas garantías adicionales.