I have the following code in a method:
aSides.foreach(as => as.side.terr match
{
case r: TerrSRiver => paintSeq :+= ((g: Graphics2D) =>
{
g.setPaintColour(ColourInt.blue)
g.fill(Polygon(as.paintStd(0.2)))
}
case _: TerrSCoast => paintSeq :+= ((g: Graphics2D) =>
{
g.setPaintColour(TerrSea.colour)
g.fill(Polygon(as.paintStd(0.2)))
}) //one case excluded for simplicity
paintSeq is declared outside the method
var paintSeq: Seq[Graphics2D => Unit] = Nil
This compiles and runs as expected. However if I add an if Statement to the first case:
case r: TerrSRiver => paintSeq :+= ((g: Graphics2D) =>
{
g.setPaintColour(ColourInt.blue)
g.fill(Polygon(as.paintStd(0.2)))
if (zoom > 50) g.setPaintColour(ColourInt.white)
}
I get an error:
type mismatch; found : Seq[swing.Graphics2D => Any] required: Seq[swing.Graphics2D => Unit] AreaESw.scala /prStratSw/src/pGrid/pUISw line 49 Scala Problem
The error refers to the paintSeq :+= method. Why is the if statement returning Any rather than Unit? I can get rid of the error by adding a line after the if statement:
val dummy = 0
However if I add in return Unit at the end:
case r: TerrSRiver => paintSeq :+= ((g: Graphics2D) =>
{
g.setPaintColour(ColourInt.blue)
g.fill(Polygon(as.paintStd(0.2)))
if (zoom > 50) g.setPaintColour(ColourInt.white)
return Unit
}
It Compiles with the following warning:
enclosing method setVisObjs has result type Unit: return value discarded
But when it runs I get the following error
Exception in thread "AWT-EventQueue-0" scala.runtime.NonLocalReturnControl$mcV$sp
Using "return ()" still gives the run time exception.
This is Scala Swing code, but I'm using Scala 2.10.3 in the JavaFx Eclipse download: 4.2.2 on Linux.
The result type of if (cond) expr
is the common base type of expr
and Unit
, just like if (cond) { expr } else { () }
See What is return type of if
statement? for details.
To get an instance of type Unit
you should use ()
literal:
if (zoom > 50) g.setPaintColour(ColourInt.white)
()
Unit
value is the companion object of type Unit
. It's not an instance of type Unit
. Type of object Unit
is Unit.type
.
return
in lambdaThe result of lambda is the result of the last statement in lambda body, so you could just add result value (in this case literal ()
) as the last line.
return
in lambda will return from the surrounding method rather than from the lambda itself using exception (NonLocalReturnControl
).
It's useful for java-style methods like this:
def firstNegative(seq: Seq[Int]): Option[Int] = {
for {
i <- seq
} if (i < 0) return Some(i)
return None
}
if (i < 0) return Some(i)
here is lambda body. Equivalent code for this method:
def firstNegative(seq: Seq[Int]): Option[Int] = {
seq.foreach{ i =>
if (i < 0) return Some(i)
}
return None
}