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.
Type of if
The result type of
if (cond) expr
is the common base type ofexpr
andUnit
, just likeif (cond) { expr } else { () }
See What is return type of
if
statement? for details.How to get Unit
To get an instance of type
Unit
you should use()
literal:Unit
value is the companion object of typeUnit
. It's not an instance of typeUnit
. Type of objectUnit
isUnit.type
.Do not use
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:
if (i < 0) return Some(i)
here is lambda body. Equivalent code for this method: