I use opencsv to parse csv files, and my code is
while( (line = reader.readNext()) != null ) { .... }
I got a compiler warning saying:
An assignment expression has type Unit
in Scala. That is the reason for your compiler warning.
There is a nice idiom in Scala that avoids the while loop:
val iterator = Iterator.continually(reader.readNext()).takeWhile(_ != null)
This gives you an iterator over whatever reader.readNext
returns.
The continually
method returns an "infinite" iterator and takeWhile
takes the prefix of that, up to but not including the first null.
(Scala 2.8)
You can use a Stream
to get what you want:
Stream.continually(reader.readLine()).takeWhile( _ ne null) foreach { line =>
//do Stuff
}
This has the added advantage of other cool stuff as well:
Stream.continually(reader.readLine()).takeWhile( _ ne null) match {
case head #:: tail => //perhaps you need to do stuff with the first element?
case _ => //empty
}
EDIT - thanks to mkneissl for pointing out I should have included this warning:
scala> Stream.continually(1).take(100000000).foreach(x=>())
scala> val s = Stream.continually(1).take(100000000)
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> s.foreach(x=>()) java.lang.OutOfMemoryError: Java heap space
Assignment in Scala doesn't return a value, Unit is similar to void in C or C++.
try
var line = ""
while ({line = reader.readNext(); line != null}) { ... }
This works because the value of the last expression in a block is returned and in this case it is a Boolean which is required by the while
You are writing Scala code they way you would write it in Java. Try doing it in a more Scala-like way. To read a text file line by line and do something with each line, try this:
import java.io.File
import scala.io.Source
Source.fromFile(new File("myfile.txt")).getLines.foreach { line =>
// Do something with the line, for example print it
println(line)
}
In your case (line = reader.readNext()) is a functional literal that returns type Unit. You may rewrite the code as follows:
while( {line = reader.readNext(); line!= null} ) { .... }