option型

option型について、もう少し調べてみました。
前回、使いにくいなと言っていたところは、getOrElseやorElseを使えばだいぶ改善されるみたいです。
getOrElseは教えていただいたので、orElseを調べてみました。

object OptionTest2{
    val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo", "" -> "Unknown")
    def get(x:String) = ({capitals get x} orElse (capitals get "")).get

    def main(args: Array[String]) {
        println (get("Japan"))
        println (get("North Pole"))
    }
}

結果

scala OptionTest2
Tokyo
Unknown

最初なんでorElseがOption型をとるのか分かんなかったんですけど、見つからなかった時の情報もMapに含めることができたので、このほうが自然なのかなあと思うようになってきました。

scalaで2次元配列を書いてみた

17章までは全部読み終わりました。けど、例を考えるところまで行かなかったので、日記更新していませんでした。

ところで、scalaで2次元配列ってどう書くんだろうって思ったのでいろいろ調べてみました

object Array2dTest {
    def main(args: Array[String]) {
        var array2d :Array[Array[Int]]=Array(Array(1,2,3),Array(4,5,6))
        println(array2d(1)(0))
    }
}

ただの配列の配列のようです。

var array2d :Array[Array[Int]]=Array(Array(1,2,3),Array(4,5,6,7,8))

みたいな書き方もエラーになりませんでした。 array2d(0)(3)にアクセスしようとしたら、例外くらいました。やっぱりただの配列の配列のようです(^^;

16.7 Listクラスの高位メソッド

List.range(1,10) map (_+1)

for(a<-List.range(1,10)) yield a+1
って、作られるものが同じなら、まったく同じ動作をするのかな?
と思ってリファレンスを見てみたらmapの引数は関数だけど、yieldはexprをとるみたいです。


var sum=0
for(a<-List.range(1,10)) yield {sum += a;sum}

結果
List(1, 3, 6, 10, 15, 21, 28, 36, 45)
ひょっとして0が9個並んだリストが作られるのかなと思っていましたけど、うまく行ったようです(^^;

16.5 リストパターン

先輩から早く16章まで行くように急かされていたので、一応報告したら、このあいだの反転のソースコードを書き換えるように言われました。
。。最初から正解教えてくれればいいのに(^^;

object ReverceList2{
    def main(args: Array[String]) {
        val listNum = List(1,2,3,4,5)
        for(arg<-ReverceList(listNum))
            println(arg)
        val listStr = List("a","b","c","d")
        for(arg<-ReverceList(listStr))
            println(arg)
    }

    def ReverceList(list: List[Any]):List[Any] = list match {
        case Nil => Nil
        case x::xs => ReverceList(xs) ::: List(x)
    }
}

これを考えてから、P284に正解が載っていたのに気づきました(^^;

15.6 Option型

また新しい型が出てきた。それもなんかすごく重要そうなのが(^^;

object OptionTest{
	def main(args: Array[String]) {
	    val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")

		println(capitals get "Japan")
		println(capitals get "North Pole")
		println(show(capitals get "Japan"))
		println(show(capitals get "North Pole"))
	}
	def show(x:Option[String]) = x match {
		case Some(s) =>s
		case None =>"Unknown"
	}
}

結果

# scala OptionTest
Some(Tokyo)
None
Tokyo
Unknown

見つからない時にnullが帰ってくると、nullチェック忘れたときに例外飛んでくることがあるし、今回のような文字列だと"見つからなかったことを表す文字列”が"決められないこともあるので、便利な気もします。
でも、正直毎回こういうコードを書くのは面倒です(^^;

15.2 パターンの種類

15章になってから、急に難しくなったような気がします(T_T)

object MatchTest{
    def main(args: Array[String]) {
        val x:Any =  CaseInt(1)
        println(x match {
            case x:CaseInt => "Int"
//          case s:CaseString => "String"   //エラーになる
        })
        println(f(x))
        println(s(x))
    }
    def f(x:Any) = x match {
        case x:CaseInt => "CaseInt="+x.n
        case y:CaseString => "CaseString="+y.s
        case _ => "Other"
    }
    def s(x:Any) = x match {
        case a:CaseTest =>"CaseTest's Subclass"
        case _ => "Other"
    }
}

abstract class CaseTest
case class CaseInt(n:Int) extends CaseTest
case class CaseString(s:String) extends CaseTest

コメントにしたところがエラーになったのがちょっとびっくりしました。絶対成立しないんですけど、こういう時ってwarningかなと思っていました。

13.4 アクセス修飾子

private[this]なんて修飾子があるので、ちょっとコード書いてみました。

class Private (val x:Int){
    private val f=x*x
    def ff {
        f
        x
        val p=new Private(1)
        p.f //こちらはコンパイルOK
        p.x
    }
}

class PrivateThis (val x:Int){
    private[this] val f=x*x
    def ff {
        f
        x
        val p=new Private(1)
        p.f //こちらはコンパイルエラー
        p.x
    }
}

C#でコードを書いていて、プロパティーでアクセスするか、直接アクセスするかを時々間違えることがあったので、scalaのやり方のほうが分かりやすそうな気がします。