2012-02-14 17 views
22

Los documentos no dicen cómo y el tutorial ignora por completo los bucles.¿Cómo se hace un rango en Rust?

+1

posible duplicado de [En óxido, ¿cuál es el equivalente idiomático? de Haskell's \ [n..m \]?] (http://stackoverflow.com/questions/15836096/in-rust-what-is-the-idiomatic-equivalent-of-haskells-nm) –

Respuesta

17

A partir de 1.0, los bucles funcionan con valores de tipos con el carácter Iterator. Aquí está el tutorial relevante para fines de bucles:

http://doc.rust-lang.org/nightly/book/for-loops.html

y para más detalles

http://doc.rust-lang.org/nightly/book/iterators.html

Si usted está interesado en la forma de operar bucles, consulte el azúcar sintáctica se describe aquí:

http://doc.rust-lang.org/std/iter/index.html

Ejemplo playpen:

fn main() { 
    let strs = ["red", "green", "blue"]; 

    for sptr in strs.iter() { 
     println!("{}",sptr); 
    } 
} 

Si lo que desea es iterar sobre un rango de números, como en for bucles de C, se puede crear un rango numérico con la sintaxis a..b:

for i in 0..3 { 
    println!("{}", i); 
} 

Si necesita tanto el índice y el elemento de una matriz, la forma idiomática de conseguir esto es con el método de Iterator::enumerate:

fn main() { 
    let strs = ["red", "green", "blue"]; 

    for (i, s) in strs.iter().enumerate() { 
    println!("String #{} is {}", i, s); 
    } 
} 

Notas:

  • Los elementos de bucle son referencias prestadas a los elementos iteratee. En este caso, los elementos de strs tienen el tipo &'static str - son punteros prestados a cadenas estáticas. Esto significa que sptr tiene el tipo &&'static str, por lo que lo desreferenciamos como *sptr.Una forma alternativa es que yo prefiero:

    for &s in strs.iter() { 
        println!("{}",s); 
    } 
    
11

En realidad, la sección Loops del tutorial cubre for bucles:

Cuando la iteración en un vector, utilizar for lugar.

for elt in ["red", "green", "blue"] { 
    std::io::println(elt); 
} 

Pero si necesitaba índices, se podría hacer algo como lo siguiente, usando la sintaxis uint::range function from the core library (o int::range o u8::range o u32::range o u64::range) y de óxido de bloques:

range(0u, 64u, {|i| C[i] = A[i] + B[i]}); 

Rust utilizado para admitir esta sintaxis equivalente pero fue eliminado más tarde:

range(0u, 64u) {|i| 
    C[i] = A[i] + B[i]; 
} 
+1

¡Gracias! Tengo curiosidad de por qué Rust tiene dos sintaxis diferentes para definiciones de funciones y bloques. Parece que podrían salvar el problema del codificador al reutilizar 'fn (args ...)' en lugar de '| args |'. – mcandre

+2

@mcandre En realidad, la sintaxis de bloque estilo Ruby '{| args | cuerpo} 'se utiliza para denotar un cierre en lugar de solo una función. También es muy conveniente para simplificar el uso de funciones anónimas como las verías en Javascript, ya que cualquier función que acepte un cierre como último argumento (como una devolución de llamada) puede escribirse después de la llamada a la función, como en el tercer ejemplo de Lindsey anterior . Finalmente, aunque Rust tiene algunos tipos diferentes de cierres, Rust puede inferir el tipo de cierre que desea cuando usa la sintaxis del bloque. Consulte también http://doc.rust-lang.org/doc/tutorial.html#closures –

+0

¿Esto todavía funciona? No puedo obtener el rango (n, n) {| i | ...} compilar. Obtengo errores extraños. –

2

nota de que al rustc 0,4 (octubre de 2012), la construcción alternativa de

range(0u, 64u) {|i| 
    C[i] = A[i] + B[i]; 
} 

parece que no se admita más.

9

for i in range(0, 100) ahora es obsoleto en favor de for i in 0..100 (según rustc 1.0.0-nightly

También digno de mención, el compilador no puede eliminar la ambigüedad cuando se utiliza un identificador. en el rango (por ejemplo, for i in 0..a), por lo que debe usar for i in (0..a), pero hay a pull request enviado para corregir esto.

+1

La ambigüedad del identificador se ha solucionado en https://github.com/rust-lang/rust/pull/21374 –

Cuestiones relacionadas