es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Convertir `Vec`s anidados a rebanadas anidadas en una función.

Estoy tratando de obtener rebanadas anidadas de un Vec anidado llamando a una función. La idea funciona para vectores simples no anidados, así que supongo que también debería funcionar para Vecs anidados.

Pude entender el problema error[E0515]: no se puede devolver un valor que hace referencia a un valor temporal en f2 (ya que recreé un nuevo Vec) y cosas básicas de tiempo de vida.

Necesito una manera de solucionarlo, pero no puedo descifrar cómo (reutilizar el Vec pasado en lugar de crear uno nuevo como valor temporal). Además, mi enfoque original parece un poco torpe.

Si eso no es imposible, ¿por qué?

¡Gracias!

“`rust
fn f1(v: &Vec<u8>) -> &str {
std::str::from_utf8(v).unwrap()
}

fn f2(v: &Vec<><u8>>) -> &[&str] {
&v.iter()
.map(|x| std::str::from_utf8(&x).unwrap())
.collect::<Vec<&str>>()[..]
}

fn main() {
let v1: Vec<u8> = vec![1, 2, 3];
f1(&v1);

<pre><code>let v2: Vec<><u8>> = vec![vec![1, 2, 3]];
f2(&v2);
</code></pre>

}
“`

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema con f2 es que está tratando de devolver una referencia a un valor temporal. La función collect() devuelve un nuevo Vec<&str> que no está ligado a la duración del Vec<><u8>> original, por lo que al intentar rebanarlo usando la sintaxis &[..] para obtener una referencia a un arreglo de &str, Rust lo previene porque el Vec temporal podría eliminarse en cualquier momento.

    Una forma de solucionar esto es asignar un nuevo Vec<&str> y luego llenarlo con referencias al Vec<><u8>> original. De esta manera, el nuevo Vec<&str> estará ligado a la duración del Vec<><u8>> original.

    Aquí tienes una versión actualizada de f2 que toma este enfoque:

    fn f2(v: &Vec<><u8>>) -> Vec<&str> {
        v.iter()
            .map(|x| std::str::from_utf8(&x).unwrap())
            .collect()
    }
    
    fn main() {
        let v1: Vec<u8> = vec![1, 2, 3];
        f1(&v1);
    
        let v2: Vec<><u8>> = vec![vec![1, 2, 3]];
        f2(&v2);
    }
    

    Ten en cuenta que el tipo de retorno de f2 se cambia a Vec<&str> en lugar de &[&str]. Esto se debe a que el nuevo Vec<&str> necesita ser dueño de sus elementos para estar ligado a la duración del Vec<><u8>> original.

    También debes tener en cuenta que se utiliza &x en lugar de &x en el cierre de map(), ya que x ya es una referencia a un Vec<u8>.

Comments are closed.