¿Cuál es la forma en Rust de llamar a un método que requiere una porción de cadena desde un `String`?
Soy un principiante en Rust (pero un programador experimentado) y estoy tratando de crear una función de utilidad simple para leer datos de un archivo JSON, pero claramente me falta una comprensión importante de Rust para lograrlo. He buscado, pero no pude hacer que funcionara con las otras preguntas de Rust. Estoy tratando de hacer algo como esto:
pub fn leer_datos_desde_json<'a, T: Deserialize<'a>, P: AsRef<path>>(ruta: P) -> T {
let resultado = std::fs::read_to_string(ruta).unwrap();
return serde_json::from_str(&resultado).unwrap();
}
El problema es que quiero proporcionar a serde_json::from_str()
el &str
que requiere, pero obtengo un String
al leer el archivo. Entonces, el compilador de Rust dice:
40 | return serde_json::from_str(&result).unwrap();
| ---------------------^^^^^^^-
| | |
| | el valor prestado no vive lo suficiente
La causa es obviamente que la variable resultado
se libera antes de que from_str()
termine con el valor, pero no pude obtener “solo la porción” con el valor. He intentado con as_str()
, &*
, &'static str
y varias otras opciones para intentar hacer que esto funcione, pero claramente me falta algo, ya que parece un caso de uso básico. Debo admitir que todavía estoy un poco confundido con “lifetime” y los genéricos involucrados, por lo que el problema podría estar allí.
davy.ai
Solución
El problema aquí es que la variable
result
es de tipoString
, yserde_json::from_str()
espera un&str
. La referencia&String
creada por&result
solo durará hasta el final del ámbito de la función, por lo que no es una solución válida.Una forma de solucionar esto es usar el método
as_str()
del tipoString
para obtener una referencia&str
a los datos subyacentes. Esto creará una referencia que durará tanto como la propiaString
.Así es como se vería la función modificada:
Observa que no hay cambios en las restricciones genéricas ni en la firma de la función.
La llamada
result.as_str()
devuelve una referencia&str
a los datos dentro de laString
. Esta referencia es válida mientras laString
misma, por lo que podemos pasarla de forma segura aserde_json::from_str()
.Con esta modificación, la función debería funcionar correctamente y devolver los datos deserializados del archivo JSON.