web-dev-qa-db-ja.com

Scalaユニットタイプ

Opencsvを使用してcsvファイルを解析しますが、コードは

while( (line = reader.readNext()) != null ) { .... }

コンパイラの警告が表示されました:

 comparing values of types Unit and Null using `!=' will always yield true
 [warn]     while( (aLine = reader.readNext()) != null ) {

Whileループはどのようにすればよいですか?

32
Don Ch

あなたの場合(line = reader.readNext())は、タイプUnitを返す関数リテラルです。次のようにコードを書き直すことができます。

while( {line = reader.readNext();  line!= null} ) { .... }
20
Vasil Remeniuk

Scalaでは、代入式の型はUnitです。これがコンパイラの警告の理由です。

Scalaには、whileループを回避する素晴らしいイディオムがあります。

val iterator = Iterator.continually(reader.readNext()).takeWhile(_ != null)

これにより、reader.readNextが返すものすべてに対してイテレータが提供されます。

continuallyメソッドは「無限」のイテレータを返し、takeWhileはそのプレフィックスを取りますが、最初のnullは含まれません。

(Scala 2.8)

71
mkneissl

Streamを使用して、必要なものを取得できます。

Stream.continually(reader.readLine()).takeWhile( _ ne null) foreach { line =>
  //do Stuff
}

これには、他のクールなものの追加の利点もあります。

Stream.continually(reader.readLine()).takeWhile( _ ne null) match {
  case head #:: tail => //perhaps you need to do stuff with the first element?
  case _             => //empty
}

[〜#〜] edit [〜#〜]-この警告を含めるべきだったと指摘してくれたmkneisslに感謝します

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
17
oxbow_lakes

あなたはScala Javaで書くのと同じようにコードを書いています。もっとScalaのような方法でやってみてください。テキストファイルを1行ずつ読んで、各行で何かをするには、この:

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)
}
10
Jesper

Scalaの割り当ては値を返しません。単位は、CまたはC++のvoidに似ています。

試してみてください

var line = ""

while ({line = reader.readNext(); line != null}) { ... }

これは、ブロック内の最後の式の値が返されるために機能します。この場合、これはブール値であり、whileで必要です。

3
Don Mackenzie