Tips04 (scala, class, test, thread)
クラス
func_mame: () => Unit class Rational(n:Int, d:Int) { private def gcd(x:Int, y:Int): Int = { if (x==0) y else if (x<0) gcd(-x, y) else if (y<0) -gcd(x, -y) else gcd(y%x, x) } private val g = gcd(n,d) val numer:Int = n/g val denom:Int = d/g def +(that:Rational) = new Rational(numer*that.denom + that.numer*denom, denom * that.denom) override def toString() = "Rational: [" + numer + " / " + denom + "]" }
Scala ではパラメーター無しのメソッドとして numer メソッドと denom メソッドを呼び出します。
Rational クラスは 3 つのプライベート・フィールド (n、d、g) を持っていますが、n と d の場合はデフォルトのプライベート・アクセスによって、g の場合は明示的なプライベート・アクセスによって、外部からは隠されています.
可変にしたい場合にはvarにする.
他のコンストラクタが必要なら -> def this(d:Int) = { this(0, d) }
単項演算子を意図する名前をつける際にはunary_~のようにする
Test
import org.scalatest.junit.AssertionsForJUnit import org.junit.Assert._ import org.junit.Test import org.junit.Before class ExampleSuite extends AssertionsForJUnit { @Before def initialize() { } @Test def verifyFun() { assert(huge === Some("huga")) } }
タプルの作成は、値を括弧でくくるだけ、という単純なものです (メソッドを呼び出す際に渡す値を括弧でくくるのとほとんど同じです)。値の抽出は「_n」メソッドを呼び出せばよいだけです (n は対象とするタプル要素の位置を表す引数であり、_1 は1 番目、_2 は 2 番目、等々です)。そうすると Java でのいわゆる java.util.Map は、基本的に 2 つの部分から成るタプルのコレクションということになります。
caseを付けるとScala のコンパイラーは、期待されるコンストラクターを生成する以上のことをします。つまり Scala のコンパイラーは、一般的な、equals() や toString()、hashCode() の実装も生成するのです
case class Person(first:String, last:String, age:Int)
case クラスが、Scala のパターン・マッチングと組み合わせて使うように設計されているため
newがいらない.
threadの作成
javaと同じ方法 +
import concurrent.ops._
spawn{hoge}
import scala.actors._, Actor._
val huge = actor {receive{case fuga}}
hoge ! "msg"
これを Scala の Actors ライブラリーで行うための最も容易な方法は、! メソッドを使う代わりに、(確認応答が受信されるまでブロックする) !? メソッドを使う方法です。
seald修飾子
「sealed」はクラスに設定できる修飾詞です。
sealedとされたクラスは、同一ファイル内のクラスからは継承できますが、別ファイル内で定義されたクラスでは継承できません。
ただし、sealedクラスを継承したクラスは、別ファイルのクラスからも継承できます。