traduccion ps4 lenguaje language juego rust

rust - ps4 - ¿Cómo iterar y filtrar una matriz?



rust traduccion (3)

Intento escribir un programa que implique el filtrado y el plegado de matrices. He estado usando The Rust Programming Language , primera edición como referencia, pero no entiendo qué sucede cuando formulo iteradores sobre arreglos. Aquí hay un ejemplo:

fn compiles() { let range = (1..6); let range_iter = range.into_iter(); range_iter.filter(|&x| x == 2); } fn does_not_compile() { let array = [1, 4, 3, 2, 2]; let array_iter = array.into_iter(); //13:34 error: the trait `core::cmp::PartialEq<_>` is not implemented for the type `&_` [E0277] array_iter.filter(|&x| x == 2); } fn janky_workaround() { let array = [1, 4, 3, 2, 2]; let array_iter = array.into_iter(); // Note the dereference in the lambda body array_iter.filter(|&x| *x == 2); }

( Patio de oxidación )

En la primera función, sigo que el iterador sobre el rango no toma posesión, así que debo tomar un &x en la lambda del filter , pero no entiendo por qué el segundo ejemplo con la matriz se comporta de manera diferente.


Como dijeron Shepmaster y bluss, puedes consultar la documentación del tipo de matriz , que menciona:

Las matrices de tamaños del 0 al 32 (inclusive) implementan los siguientes rasgos si el tipo de elemento lo permite:

  • IntoIterator (implementado para &[T; N] y &mut [T; N] )

Como se dice, esto es solo para referencias, y se refleja en su tipo de Item : type Item = &''a T y type Item = &''a mut T


En casos como este, es muy útil obligar al compilador a decirle el tipo de la variable. Activaremos un error de tipo asignando el argumento de cierre a un tipo incompatible:

array_iter.filter(|x| { let () = x; true });

Esto falla con:

error[E0308]: mismatched types --> src/main.rs:12:33 | 12 | array_iter.filter(|x| { let () = x; true }); | ^^ expected &&{integer}, found () | = note: expected type `&&{integer}` found type `()`

Ahora sabemos que el tipo de x es a &&{integer} - una referencia a una referencia a algún tipo de número entero. Entonces podemos compararlo con eso:

fn hooray() { let array = [1, 4, 3, 2, 2]; let array_iter = array.into_iter(); array_iter.filter(|&&x| x == 2); }

La pregunta ahora se convierte en "¿por qué es una referencia a una referencia"? La versión corta es que el iterador de una matriz devuelve referencias (vea el type Item = &''a T parte). Además, el Iterator::filter pasa una referencia al cierre para evitar el movimiento y, posteriormente, la pérdida de tipos no Copy .


Las matrices son del tipo [T; N] [T; N] en Rust, para cualquier elemento tipo T y un número constante N Es una matriz de tamaño fijo.

Rust no implementa iteradores de valor por defecto para matrices en este momento. Todas las matrices fuerzan a las divisiones (tipo [T] ) y los métodos de división están disponibles en la matriz debido a esto. Las matrices también obtienen el iterador de la sección, que se llama std::slice::Iter<''a, T> y tiene elementos de tipo &''a T : ¡itera por referencia!

Esta es la razón into_iter() cual into_iter() en un Range<i32> produce un iterador de into_iter() e into_iter() en un [i32; 5] [i32; 5] produce un iterador de &i32 .

Si necesita por iteradores de valor para matrices, se han implementado en el ecosistema más amplio, ver (1) y (2) .