4

When working with the standard widget toolkit (SWT), I usually use something like this to define my GridLayout:

layout.marginTop = layout.marginBottom = 
    layout.marginLeft = layout.marginRight =
        layout.horizontalSpacing = layout.verticalSpacing = 20

It works in java but not in scala. It gives me type mismatch; Found: Unit Required: Int.

So how can this solve it?

f4lco
  • 3,728
  • 5
  • 28
  • 53

3 Answers3

7

You cannot do this in one line in scala because the result type of an assignment expression (e.g. a = b) is Unit. You'd have to have 6 separate calls:

layout.marginTop = 20
layout.marginBottom = 20 
... etc

Why is the result type of an assignment Unit and nmot the assigned value? I believe this was chosen for performance reasons as outlined in this question.

There is a related question on assignment which points out that at declaration site, it is possible via:

val a, b, c = X
Community
  • 1
  • 1
oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
  • ...and I thought scala is about syntactic sugar and "type less, do more" philosophy :/ – f4lco May 17 '11 at 13:17
  • @phineas If you want to type less to do more in SWT, be sure to check out Dave Orme's [XScalaWT](http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:simplifying_swt_with_scala) library. – Jean-Philippe Pellet May 17 '11 at 13:19
  • @phineas - this is one of those very few areas where Java can be more concise. Note that the example you gave is a rather nasty case of bad encapsulation, however! It's a code pattern that I would see immediately as a "smell" – oxbow_lakes May 17 '11 at 13:20
  • I have to admit, Swing is modelled a bit better (but lacks certain features). – f4lco May 17 '11 at 14:24
1

You have to write multiple assignments separately. As the compiler says, an assignment in Scala returns Unit, which can be seen as Java's void.

Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234
1

You could do

def assign[A](a:A)(fs: (A => Unit)*) = fs.foreach(_(a))

val r = new java.awt.Rectangle
assign(20)(r.x=_, r.y=_, r.width=_, r.height=_)

But this is clearly worse than writing everything separately. But at least you don't have to type "layout" every time in Scala:

val rectangle = new java.awt.Rectangle
import rectangle._
x = 20
y = 20
width = 20
height = 20
Landei
  • 54,104
  • 13
  • 100
  • 195