コップ本をScala 3.3.1でやってみる
p.53 hello.scalaでファイルから実行でエラー
@main def entryPoint() =が必要
mainの話はp.85に出てくる
p.54 mainのエントリポイントにargsが必要
@main def entryPoint(args: String*) = { ... }
型付きでコマンドライン引数を受け取るみたい
p.57 全部同じセマンティクス
セマンティクスはコンパイラから見た意味
code:pa.scala
@main def entryPoint(args: String*) = {
args.foreach(arg => println(arg))
args.foreach((arg: String) => println(arg))
args.foreach(println)
}
p.67 タプルの添字は1-indexedになっている。
静的に型付けされたタプルは先頭を1とする伝統がすでに確立しているからだ。
p.73 argsはSeq[String]なためArray[String]に変換が必要だった
println(formatArgs(args.toArray))
p.87 fscがない?ので scalacでやる
p.100 メソッド呼び出しの括弧をつけるかつけないか
副作用を持つ場合は、括弧をつける
副作用を持たない場合は、括弧をつけない
p.124 Scalaの演算子はJavaから見るとmangleされた表現になる
:->は$colon$minus$greaterになる
Scalaのfor式は、反復処理のスイスアーミーナイフである。
p.158 プレースホルダー構文。下2行は同じセマンティクス
List(-1, 0, 1).filter(_ > 0)
List(-1, 0, 1).filter(x => x > 0)
p.160 部分適用。引数の一部省略して記述できる
code:partially.scala
def sum(a:Int, b:Int) => a + b
val a = sum _
val b = sum(10, _:Int)
a(1,2) // 3
b(4) // 14
アンダーバーによる省略を実際どの程度使うのか気になる
p.165 連続パラメータにSeqを渡す : _*記法がある
def echo(args: String*) = for (arg <- args) println(arg)
echo(Seq("a", "b", "c"): _*)
p.168 末尾再帰であればオーバーヘッドがかからない
whileループに書き換えるより末尾再帰になるように書き直す方が良さそう
p.193 パラメータフィールドでパラメータとフィールドを兼ねられる
Kotlinのそれと同じな気がする
p.213
JavaのObjectとScalaのAnyRefは交換可能だが、AnyRefだけ使うことが推奨
p.224 シンインターフェース/リッチインターフェース
シン thin とリッチ rich
traitでリッチインターフェースを提供できる
p.233 traitの合成は線形化されて適用される
p.272 matchパターンで変数パターンを使うと、任意のオブジェクトにマッチする
その時点の値でパターンマッチするわけではない
定数であればそのようになる
本来定数なものはthis.pi,obj.pi, piで回避できる
p.279 パターンガードで条件式が書ける
code:scala
case n:Int if 0 < n => ...
p.291 Int max Intの計算にimplicit def intToRational(x: Int): Rational = new Rational(x)が暴発して困った
一旦コメントアウトして解決。自動的にRational型になってエラーに
vscodeフォーマッタが調子悪いのかもしれない
p.294 def showで改行されない
code:scala
def show(e: Expr) = println(s"${f.format(e)}\n\n")
printlnに改行コードが含まれていないため、式ごとに改行されなくなっていた
改行コード含め、文字列全体をprintlnにして解決
p.297 Nil == List()が成り立つ
p.323 デバッグとして明示的に型アノテーションをつけてみよう。エラーが分かりやすくなるかも