あるプログラマの日記

プログラマのメモ、出来事、考えたこと、勉強とかの雑記

[Scala] java のアレは scala でどう書くの

基本的なことでも慣れないうちは、どう書けばよいかと、ググる日々..
scala でプログラミングし出して慣れない scalajava のアレはどう書くのか?
と簡単な処理でも勝手が違うので少し戸惑った事。

byte バッファ

java だと

byte[] buffer = new byte[size];

scala で 配列は Array[T] になるので byte 配列は

val buffer = new Array[Byte](size)

DataInputStream の readFully メソッドに java と同じ byteバッファとして指定可能。

import java.io.{File,FileInputStream,DataInputStream}
..snip..
val file = new File(filename)
val in = new DataInputStream(new FileInputStream(file))
val size = file.length.toInt
val buffer = new Array[Byte](size)
using[DataInputStream, Unit) { in => in.readFully(buffer) }
..snip..

break

scala 2.8 から使用可能。ライブラリで対応している。

breakable { .. } で囲ってそのブロック内のループ処理から break
してループを抜ける。

import scala.util.control.Breaks.{break, breakable}
..snip..
        breakable {
            while (true) {
                val ok = .. // 何かの処理
                if (ok) break
            }
        }
..snip..

break メソッドで、例外を投げて、breakable メソッドで
例外をキャッチして処理の流れを制御している。
正常処理の流れを例外で制御しているのが、普段、java のコードレビューで
やってはダメと指摘している手前、ちょっと.. 微妙かも

scala/util/control/Breaks.scala の中身(抜粋)

package scala.util.control

..snip.. // 省略

class Breaks {	
  private val breakException = new BreakControl
	
  /** A block from which one can exit with a `break''. */
  def breakable(op: => Unit) {
    try {
      op
    } catch {
      case ex: BreakControl => 
        if (ex ne breakException) throw ex
    }
  }
	 
..snip.. // 省略
	
  /* Break from dynamically closest enclosing breakable block
   * @note this might be different than the statically closest enclosing
   * block!
   */
  def break() { throw breakException }
}

object Breaks extends Breaks
	
private class BreakControl extends ControlThrowable