🔍
手を動かしてわかる Scala のスコープ ─ 九九表で学ぶ変数の見える範囲とリファクタリング
Scala のスコープを “手を動かして” 体感しよう 🔥
1. まずは REPL を開こう
ターミナルで scala
(または Ammonite 派なら amm
)と叩いて REPL を起動してください。
$ scala
Welcome to Scala 2.13.16 (OpenJDK 64-Bit Server VM, Java 17.0.15).
Type in expressions for evaluation. Or try :help.
以降、 scala>
の行は コピペして Enter するだけで OK です!
2. かけ算九九表を while で書いてみる
まずは本の例そのまんま、命令型スタイルの printMultiTable
を REPL に貼り付けてみましょう。
def printMultiTable(): Unit = {
var i = 1 // ← ここでは i がスコープにいる
while (i <= 10) {
var j = 1 // ← ここでは i と j が見える
while (j <= 10) {
val prod = (i * j).toString // ← i, j, prod が見える
var k = prod.length // ← i, j, prod, k が見える
while (k < 4) {
print(" ")
k += 1
}
print(prod)
j += 1
}
println() // ← i だけ見える。j, prod, k は見えない
i += 1
}
}
scala> printMultiTable()
1 2 3 ... 10 // ← ちゃんと九九表が出れば成功!
3. シャドウイングって何?(val a の実験)
同じスコープに 同じ名前の変数 は定義できません。
でも “外” と “内” であれば 上書き(シャドウイング) できます。
val a = 1
{
val a = 2 // ← 外側の a を “隠す” 新しい a
println(a) // => 2
}
println(a) // => 1
- 中カッコの中では 内側 a = 2 が見える
- 外に出ると 外側 a = 1 が見える
これがシャドウイングです。
個人の好みですが、可読性重視なら なるべく違う名前 を付けた方が吉です。
4. 関数型っぽくリファクタしてみる ✨
while と var で書いた printMultiTable
を、 val + for 式 + ヘルパー関数 で書き換えるとこうなります。
// 1段分を Seq[String] で返す
def makeRowSeq(row: Int) =
for (col <- 1 to 10) yield {
val prod = (row * col).toString
val padding = " " * (4 - prod.length)
padding + prod
}
// 1段を String に連結
def makeRow(row: Int) = makeRowSeq(row).mkString
// 表全体を 1つの文字列に
def multiTable() = {
val tableSeq =
for (row <- 1 to 10)
yield makeRow(row)
tableSeq.mkString("\n")
}
scala> println(multiTable())
1 2 3 ... 10
2 4 6 ... 20
3 6 9 ... 30
...
10 ... 100
どこがうれしい?
命令型 (while) | 関数型 (for + val) |
---|---|
状態を更新する変数 i, j, k が大量に出てくる |
val なので再代入ナシ、バグりにくい |
“計算 + 出力” が入り混じる |
副作用ゼロ の関数 (multiTable はただの文字列を返す) |
ユニットテストしづらい | 返り値の文字列を比較するだけでテスト可 |
5. まとめ 🎯
- Scala では
{}
を開くたびに新しいスコープ ができる - 同じスコープで同じ名前は NG、でも内側でなら シャドウイング できる
- while & var で書いたら、一度 val + for 式 に置き換えてみよう
- 副作用が減り、テストしやすくなる
Scala に疲れたら ☕ を飲みつつ、小さなスクリプトで “実験 → 体感” を繰り返すと理解がグッと深まります。Enjoy Scala!
参考文献
- Martin Odersky, Lex Spoon, Bill Venners, Scalaスケーラブルプログラミング 第4版, オライリー・ジャパン, 2021, 第7章より着想を得て執筆。
Discussion