decadence

個人のメモ帳

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クラスを継承したクラスは、別ファイルのクラスからも継承できます。