Created
August 7, 2011 09:40
-
-
Save kijuky/1130245 to your computer and use it in GitHub Desktop.
scalaのmatchでイレイジャと戯れる
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.measure.Measurable | |
import javax.measure.quantity.Quantity | |
import javax.measure.unit.Unit | |
// 任意の型からMeasurable[Q]を作る…前にargにMeasurable[Q]が渡されたときを考える。 | |
def toMeasurable[Q <: Quantity](arg: Any)(implicit manifest: ClassManifest[Q]): Measurable[Q] = { | |
arg match { | |
case measurable: Measurable[_] => | |
try { | |
// measurable の型パラメータが正しいことを保証するために | |
// 要求されたクォンティティ Q と次元が等しいかどうかをチェック | |
// (次元が等しければ、Q の単位に変換できる) | |
val unit = manifest.erasure.getField("UNIT").get(null).asInstanceOf[Unit[Q]] | |
measurable.doubleValue(unit) // コンパイルエラー。Measurable#doubleValue(v: _)を呼び出せない | |
} catch { | |
// 次元が等しくなかった場合 | |
case illegalQuantity: ConversionException => | |
throw new IllegalArgumentException(illegalQuantity) | |
} | |
measurable // コンパイルエラー。Measurable[_] は Measurable[Q] ではない。 | |
} | |
} | |
// 型パラメータが _ である measurable は、 | |
// その型パラメータを使っているメソッド doubleValue を呼び出せない。 | |
// なので… | |
def toMeasurable[Q <: Quantity](arg: Any)(implicit manifest: ClassManifest[Q]): Measurable[Q] = { | |
arg match { | |
case measurable: Measurable[Q] => // 警告: イレイジャにより型情報がなくなる | |
try { | |
val unit = manifest.erasure.getField("UNIT").get(null).asInstanceOf[Unit[Q]] | |
measurable.doubleValue(unit) | |
} catch { | |
case illegalQuantity: ConversionException => | |
throw new IllegalArgumentException(illegalQuantity) | |
} | |
measurable | |
} | |
} | |
// パターンマッチに Measurable[Q] を書くと警告が出る。 | |
// この警告を出さないようにするには、キャストする。 | |
def toMeasurable[Q <: Quantity](arg: Any)(implicit manifest: ClassManifest[Q]): Measurable[Q] = { | |
arg match { | |
case measurable: Measurable[_] => | |
val measurableQ = measurable.asInstanceOf[Measurable[Q]] | |
try { | |
val unit = manifest.erasure.getField("UNIT").get(null).asInstanceOf[Unit[Q]] | |
measurableQ.doubleValue(unit) // OK | |
} catch { | |
case illegalQuantity: ConversionException => | |
throw new IllegalArgumentException(illegalQuantity) | |
} | |
measurableQ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment