This chaotic entry should describe migration from Java. using mapsScala maps are different from Java maps, because they return an Option.
Map map = new HashMap<int,String>
String s = map.get(0)
if (s!=null) {...}
|
map.get(0) match {
case Some(s) => ...
case None => // do nothing
}
|
Scala offers a lot of different ways to achieve the same. You can use a for-comprehension on an option
for(val theValue <- map.get(key)) {
theValue.myMethod
}
This is the same as writing map.get(key).foreach(.myMethod), which personally I
do not find very informative but it's there. some tips when rewriting source code
Uff, just translated the code generation parts of the pattern matching phase from Java(or rather: Pico) to Scala.
1500 lines became 1530 lines. This is probably the most tedious and boring task one could do, but there are
things that are worth remembering.
Here's a list of what to do when translating a source file from Java (before 1.5, no generics!) to Scala
(some people might take this as a little description of syntax changes):
- Import descriptors: Turn
import xxx.* into import xxx._
- remove
public modifier from class declaration
- Move the primary constructor of
class X extends Foo { ... } up. This yields a
class X(arg1:T1,...,argsN:TN) extends Foo(...) { ... }. If you have several constructors,
choose one to be the primary one.
- If you extend a class, nothing changes, but instead of
implements myInterface, write
extends myInterface if its the only one. Write with i1 ... with iN if there are
several (this is a oversimplified description, it might go wrong in some cases that I won't go into here.)
- Of course, change all declarations
T x into x:T
- While you're at it, replace field declarations
T x; with value or variable declarations
var x:T = _;. If you don't supply a default value, your class must become abstract
-
If you made Java fields just to store constructor arguments,
omit those and add
val to your primary
constructor argument class X(arg1:T1,...,val argJ: TJ,
... argsN:TN). Sorry this does not work with mutable
fields (var).
- remove
public modifier from method definitions. Turn definition T m(args) {...}
into def m(args): T = {...}. Pay attention to that equal sign.
- Another thing about type declarationg:
T x[] and T[] x both become
x: Array[T]. If you also want to initialize an array, turn T x[] = { y1,...,yN }
into val x = Predef.Array[T](y1,...,yN).
- Turn all
for loops into while loops. You could also use for-loops, but
it takes to long to write. Pay attention to not forget the increment, decrement operations, which you
of course have to move to the end of the block. for(int i = ...; test; inc) {body} becomes
val i = ...; while(test) {body; inc}. Of course this pollutes the scope with variables (which in
Java you might have reused in other loops), but those you can fix by renaming later.
- Ah yes, say goodbye to
x++, change it to x and to x = x + 1;
- If you have
static stuff in a class X, create an object X of the same
name and move the translated thingies there (without the static modifier). Change access sites
of a static method or field into qualified access ( i.e. foo becomes X.foo ).
For most uses of static, this is enough, e.g. the main method.
switch statements require more care. First turn
case pat: into case pat =>. Now you should take some more involved
measures: scala does not need a break, which is convenient, but an unmentioned
default case will not be ignored by lead to a runtime error. If your switch does not have a default case,
add one case _ => (the right-hand side is empty.)
- remove all
return statements. Those at the end you don't need, returns that are
somewhere in the middle of your method body are either supported or unsupported, depending on whether
they get translated via some syntactic quirks. Add exit flag variables in loops and stuff. The same
holds for break statements in for/while loops. Get rid of those things.
After all this, you will probably not appreciate scala a lot, because your program has not become any nicer.
Now is the time to fix all those syntax errors that you introduced. Only when you got all these and your
test suites run through you can look into ways to take advantage of Scala. For instance, replace all uses
of collection classes with the equivalent (or better) scala ones. Use higher order functions to express
things concisely. I'll get back to this page to add some cures for those "Java smells".
Problems
Even if you have a package of the same name, you won't be able to access package-protected things from
Java. Either you translate the classes with those parts you want to access, too, or you make the public.
|