Тип Единицы 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 ) {

Как я должен сделать цикл с условием продолжения?

31
задан Don Ch 17 June 2010 в 14:55
поделиться

5 ответов

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

while( {line = reader.readNext();  line!= null} ) { .... }
20
ответ дан 27 November 2019 в 21:25
поделиться

Вы можете использовать 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
ответ дан 27 November 2019 в 21:25
поделиться

Вы пишете код 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)
}
10
ответ дан 27 November 2019 в 21:25
поделиться

Присваивание в Scala не возвращает значение. Единица измерения аналогична void в C или C ++.

try

var line = ""

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

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

3
ответ дан 27 November 2019 в 21:25
поделиться

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

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

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

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

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

(Scala 2.8)

71
ответ дан 27 November 2019 в 21:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: