Как каждый делает абстракцию управления Scala в повторении до?

Я - Peter Pilgrim. Я наблюдал, что Martin Odersky создал абстракцию управления в Scala. Однако я, еще может казаться, не повторяю его в ИДЕЕ IntelliJ 9. Действительно ли это - IDE?

package demo

class Control {

  def repeatLoop ( body: => Unit ) = new Until( body )

  class Until( body: => Unit ) {
    def until( cond: => Boolean ) {
      body;
      val value: Boolean = cond;
      println("value="+value)
      if ( value ) repeatLoop(body).until(cond)
      // if  (cond) until(cond)
    }
  }

  def doTest2(): Unit = {
    var y: Int = 1
    println("testing ... repeatUntil() control structure")
    repeatLoop {
      println("found y="+y)
      y = y + 1
    }
    { until ( y < 10 ) }
  }

}

Чтения сообщения об ошибке:

Information:Compilation завершается с 1 ошибкой и 0 предупреждениями
Ошибка Information:1
Предупреждения Information:0
C:\Users\Peter\IdeaProjects\HelloWord\src\demo\Control.scala
Error:Error:line (57) ошибка: Control.this.repeatLoop ({
scala.this. Predef.println ("нашел y =". + (y));
y = y. + (1)
}) типа Control.this. До не берет параметры
repeatLoop {

В функции с приправой карри тело, как могут думать, возвращает выражение (значение y+1) однако, параметр тела объявления repeatUntil ясно говорит, что это может быть проигнорировано или нет?

Что означает ошибка?

10
задан oxbow_lakes 14 June 2010 в 09:15
поделиться

3 ответа

Вот решение без StackOverflowError .

scala>   class ConditionIsTrueException extends RuntimeException
defined class ConditionIsTrueException

scala>   def repeat(body: => Unit) = new {
 |     def until(condition: => Boolean) = { 
 |       try {
 |         while(true) {
 |           body
 |           if (condition) throw new ConditionIsTrueException
 |         }   
 |       } catch {
 |         case e: ConditionIsTrueException =>
 |       }   
 |     
 |     }   
 |   }
repeat: (body: => Unit)java.lang.Object{def until(condition: => Boolean): Unit}

scala> var i = 0              
i: Int = 0

scala> repeat { println(i); i += 1 } until(i == 3)
0
1
2

scala> repeat { i += 1 } until(i == 100000)       

scala> repeat { i += 1 } until(i == 1000000)

scala> repeat { i += 1 } until(i == 10000000)

scala> repeat { i += 1 } until(i == 100000000)

scala> 

По словам Джеспера и Рекса Керра, это решение без исключения.

def repeat(body: => Unit) = new {
  def until(condition: => Boolean) = { 
    do {
      body
    } while (!condition)
  }   
}
10
ответ дан 3 December 2019 в 15:21
поделиться

Как насчет одного лайнера для , повторять до .

def repeat(b: => Unit) = new AnyRef {def until(c: => Boolean) {b; while (! c) b}}

Что, например, дает: -

scala> repeat {
     |   println("i = "+i)
     |   i+=1
     | } until (i >= 10)
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
6
ответ дан 3 December 2019 в 15:21
поделиться

Вы не Не нужна вторая пара скобок, следует использовать:

repeatLoop (x) until (cond) //or...
repeatLoop {x} until {cond}

А не:

repeatLoop {x} { until(cond) } //EXTRA PAIR OF BRACES

Ошибка означает , что Scala думает, что вы пытаетесь вызвать метод с подписью, например:

def repeatLoop(x: => Unit)(something: X) //2 parameter lists

И может найти нет такого метода. Говорят, что "repeatLoop (body)" не принимает параметров . Полный листинг кода для решения, вероятно, выглядит примерно так:

object Control0 {
  def repeatLoop(body: => Unit) = new Until(body)

  class Until(body: => Unit) {
    def until(cond: => Boolean) {
      body;
      val value: Boolean = cond;

      if (value) repeatLoop(body).until(cond)
    }
  }


  def main(args: Array[String]) {
    var y: Int = 1
    println("testing ... repeatUntil() control structure")
    repeatLoop {
      println("found y=" + y)
      y += 1
    }.until(y < 10)
  }
}

Здесь можно сделать два полезных наблюдения:

  1. Решение не является хвостовым рекурсивным и приведет к StackOverflowError для длинные итерации (попробуйте while (y <10000) )
  2. Мне кажется, что до неправильный путь (было бы более естественно остановиться, когда условие станет истинным, а не продолжай, пока это правда).
8
ответ дан 3 December 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: