Así, mientras que el trabajo de mi camino a través de la «Scala para los Impacientes» me encontré preguntándome: se Puede utilizar un Scala de bucle sin una secuencia?

Por ejemplo, hay un ejercicio en el libro que se le pide construir un contador de objetos que no se incremente el pasado Entero.MAX_VALUE. Con el fin de poner a prueba mi solución, escribí el siguiente código:

var c = new Counter
for( i <- 0 to Integer.MAX_VALUE ) c.increment()

Esto arroja un error: secuencias no puede contener más de Int.MaxValue elementos.
A mí me parece que significa que Scala es la primera asignación y rellenar un objeto de secuencia, con los valores de 0 a Entero.MaxValue y, a continuación, hacer un bucle foreach en la que la secuencia de objetos.

Me doy cuenta de que yo podría hacer esto en su lugar:

var c = new Counter
while(c.value < Integer.MAX_VALUE ) c.increment()

Pero, ¿hay alguna manera de hacer un tradicional estilo C bucle for con la instrucción for?

OriginalEl autor Adam Ness | 2011-09-08

4 Comentarios

  1. 18

    De hecho, 0 to N en realidad no rellenar de cualquier cosa con números enteros de 0 a N. En lugar crea una instancia de scala.collection.immutable.Range, que aplica sus métodos para todos los enteros generados sobre la marcha.

    El error que se encontró es sólo porque usted tiene que ser capaz de ajustar el número de elementos (si existe realmente o no) en la parte positiva de una Int en el fin de mantener el contrato para la length método. 1 to Int.MaxValue funciona bien, como hace 0 until Int.MaxValue. Y el último es a lo que el bucle while es hacer de todos modos (to incluye el extremo derecho, until omite).

    De todos modos, desde la Scala for es muy diferente (mucho más genérico) criatura de la C for, la respuesta corta es no, usted no puede hacer exactamente la misma cosa. Pero usted probablemente puede hacer lo que quiera con for (aunque tal vez no tan rápido como se desea, ya que hay algunos penalización de rendimiento).

    OriginalEl autor Rex Kerr

  2. 5

    Wow, algunas buenas respuestas técnicas para una simple pregunta (que es buena!) Pero en caso de que alguien está buscando una respuesta simple:

    //start from 0, stop at 9 inclusive
    for (i <- 0 until 10){
        println("Hi " + i)
    }
    
    //or start from 0, stop at 9 inclusive
    for (i <- 0 to 9){
        println("Hi " + i)
    }

    Rex señaló, «a» incluye el derecho de extremo», hasta que» omite.

    OriginalEl autor user85116

  3. 4

    Sí y no, depende de lo que usted está pidiendo. Si usted está preguntando si se puede iterar sobre una secuencia de números enteros, sin tener que generar que la secuencia de la primera, entonces sí se puede, por ejemplo a través de secuencias:

    def fromTo(from : Int, to : Int) : Stream[Int] = 
      if(from > to) {
        Stream.empty
      } else {
        //println("one more.") //uncomment to see when it is called
        Stream.cons(from, fromTo(from + 1, to))
      }

    A continuación:

    for(i <- fromTo(0, 5)) println(i)

    La escritura de su propia iterador mediante la definición de hasNext y lo siguiente es la otra opción.

    Si usted se está preguntando si usted puede utilizar el ‘para’ sintaxis para escribir un «nativo» bucle, es decir, un bucle que trabaja por el incremento de algunos nativos entero en lugar de iterar sobre los valores producidos por una instancia de un objeto, entonces la respuesta es, que yo sepa, no. Como usted puede saber, ‘para’ comprensiones son azúcar sintáctico para una combinación de llamadas a flatMap, filtro, mapa y/o foreach (todos definidos en el FilterMonadic rasgo), dependiendo de la anidación de los generadores y sus tipos. Usted puede tratar de compilar algunos de bucle y la impresión de su compilador representación intermedia con

    scalac -Xprint:refchecks

    para ver cómo están expandidos.

    Wow, una difícil respuesta, pero una buena. Estoy aprendiendo Scala, así que he usado un montón de términos que sólo estoy apenas se conocen, pero gracias.
    La definición de fromTo puede ser simplificado mediante el método iterate en el Stream (o Iterator) objeto acompañante. Algo a lo largo de las líneas de: def fromTo(from: Int, to: Int) = Stream.iterate(from, to - from)(_ + 1). Pero el uso de from until to es más idiomático y logra la misma cosa.

    OriginalEl autor Philippe

  4. 2

    Hay un montón de estos por ahí, pero no puedo ser molestado en buscar en google en el momento. La siguiente es bastante canónica:

    @scala.annotation.tailrec
    def loop(from: Int, until: Int)(f: Int => Unit): Unit = {
      if (from < until) {
        f(from)
        loop(from + 1, until)(f)
      }
    }
    
    loop(0, 10) { i =>
      println("Hi " + i)
    }

    OriginalEl autor Derek Wyatt

Dejar respuesta

Please enter your comment!
Please enter your name here