Prestar en vez de mover: la referencia compartida &T
Consulta un texto conservando su dueño. Distingue recibir String de recibir &str y comprueba qué valores acepta cada firma.
Quieres medir un texto y mostrarlo después junto con el resultado. Ya sabes que pasar un String por valor puede transferir su propiedad. Pero esta consulta necesita acceso al texto, sin quedarse con él.
Observa qué pide la firma
fn longitud_bytes(texto: String) -> usize { texto.len()}fn main() { let informe = String::from("listo"); let longitud = longitud_bytes(informe); // println!("{informe}: {longitud} bytes"); // Error E0382 al descomentar. println!("{longitud} bytes");}La firma recibe String, así que la llamada mueve el valor hacia el parámetro texto. La función devuelve la longitud y, en esta salida normal, destruye el String que recibió. El llamador conserva el número, pero ya no puede usar informe.
Para la necesidad planteada, podemos cambiar el contrato de acceso.
Consulta mediante una vista de texto
fn longitud_bytes(texto: &str) -> usize { texto.len()}fn main() { let informe = String::from("listo"); let longitud = longitud_bytes(&informe); println!("{informe}: {longitud} bytes");}&str es una vista compartida de texto UTF-8. Aquí permite consultar los bytes del texto sin adquirir la propiedad del String. En &informe, el & crea una referencia; Rust puede convertir esta referencia a String en la vista &str que recibe la función.
Después de la llamada, informe continúa siendo el dueño del mismo texto y puede usarse para imprimirlo. El préstamo de esta consulta no crea una copia del contenido ni libera el almacenamiento del dueño.
usize es el tipo entero que devuelve .len(). Esta operación cuenta bytes: "ñ" ocupa dos bytes UTF-8. Contar caracteres o símbolos percibidos por una persona es otro contrato.
Elige según lo que necesita el llamador
| Necesidad | Firma adecuada para estos ejemplos | Qué conserva el llamador |
|---|---|---|
| Entregar el texto a una operación que lo consume | Parámetro String |
Pierde el uso del binding original, salvo que reciba un valor de vuelta. |
| Consultar los bytes y mostrar después el texto original | Parámetro &str |
Conserva su String y recibe el resultado de la consulta. |
Una firma con String puede ser correcta cuando la operación necesita adquirir propiedad. Elegir una referencia responde al contrato de esta consulta; no es una regla que prohíba recibir valores por propiedad.
Acepta también un literal
fn longitud_bytes(texto: &str) -> usize { texto.len()}fn main() { let propio = String::from("ñ"); let desde_dueno = longitud_bytes(&propio); let desde_literal = longitud_bytes("ñ"); println!("{propio}: {desde_dueno} y {desde_literal} bytes");}La misma función admite una vista sobre el texto de un String y un literal. Una firma &String exigiría una referencia a ese tipo concreto; para consultar bytes, &str admite ambas entradas.
El tipo de acceso también limita las operaciones disponibles. Un &str no permite modificar el texto a través de esa vista. Más adelante estudiarás tipos con mutabilidad interior; una referencia compartida &T no significa que todo dato alcanzable quede congelado en cualquier tipo.
Qué preparación sigue
Esta lección trabaja consultas que devuelven un número. Devolver una referencia, relacionar varias vidas de datos y modificar mediante un préstamo exclusivo necesitan sus propios ejemplos. Puedes estudiar primero cómo conservar el dueño durante una consulta sin introducir todavía anotaciones de lifetimes.
Comprueba el contrato
- Predice el error del primer ejemplo antes de descomentar el uso de
informe. - Ejecuta la versión con
&stry verifica que puedes volver a usar el dueño. - Comprueba texto vacío, ASCII y
"ñ". Distingue la longitud en bytes de la cantidad de caracteres. - Decide qué firma usarías si necesitas medir y conservar el texto, y cuál si necesitas entregarlo definitivamente a otra operación.
Consultar con una firma dada demuestra que puedes implementarla y usarla. Elegir el contrato requiere además justificar la decisión en un caso nuevo. Estas preguntas son práctica manual; las futuras comprobaciones evaluadas de la familia B distinguirán ambas capacidades.