Тип устройства Scala - PullRequest
       15

Тип устройства Scala

31 голосов
/ 17 июня 2010

Я использую 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?

Ответы [ 5 ]

71 голосов
/ 17 июня 2010

Выражение присваивания имеет тип Unit в Scala. Вот причина предупреждения вашего компилятора.

В Scala есть хорошая идиома, которая избегает цикла while:

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

Это дает вам итератор для всего, что возвращает reader.readNext.

Метод continually возвращает «бесконечный» итератор, а takeWhile принимает префикс этого, вплоть до первого нулевого, но не включая.

(Scala 2.8)

20 голосов
/ 17 июня 2010

В вашем случае (line = reader.readNext ()) это функциональный литерал, который возвращает тип Unit. Вы можете переписать код следующим образом:

while( {line = reader.readNext();  line!= null} ) { .... }
17 голосов
/ 17 июня 2010

Вы можете использовать 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
}

РЕДАКТИРОВАТЬ - спасибо 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
10 голосов
/ 17 июня 2010

Вы пишете Scala-код так, как если бы вы писали его на Java. Попробуйте сделать это более похожим на Scala способом. Чтобы читать текстовый файл построчно и что-то делать с каждой строкой, попробуйте следующее:

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)
}
3 голосов
/ 17 июня 2010

Назначение в Scala не возвращает значение, Unit аналогичен void в C или C ++.

попробовать

var line = ""

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

Это работает, потому что возвращается значение последнего выражения в блоке, и в данном случае это логическое значение, которое требуется , тогда как

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...