Я - 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 ясно говорит, что это может быть проигнорировано или нет?
Что означает ошибка?
Вот решение без 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)
}
}
Как насчет одного лайнера для , повторять до .
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
Вы не Не нужна вторая пара скобок, следует использовать:
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)
}
}
Здесь можно сделать два полезных наблюдения:
StackOverflowError
для длинные итерации (попробуйте while (y <10000)
) до
неправильный путь (было бы более естественно остановиться, когда условие станет истинным, а не продолжай, пока это правда).