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のやり方のほうが分かりやすそうな気がします。