はじめに、Scalaはすごい
勉強するごとに感じる。 先日も会社の先輩にScalaで書いたコードを見せて頂いのだが、まるで自分の書いたものとは違った。 Scalaという名前には「スケーラブルに開発者のレベルに応じて進化する」という意味があるが、まさにそのとおりだと感じた。 他の言語でももちろんメタ的な属性や、様々な組み込み関数を駆使することで開発者のレベルによって差が出るものではあるが、全然読めない…とはならない。 少なくとも私の使用しているPythonではそんなことはない。 しかしScalaの場合は「全く読めない」のだ。(それが会社でただしいかどうかは別にして)これは非常に面白い言語だと感じる理由の一つだった。 自身のレベルアップを如実に感じることができる言語、それがScalaだ。
書籍はもちろんコップ本と参考に記載するいくつかのサイトを使用させて頂いている。

- 作者: Martin Odersky,Lex Spoon,Bill Venners,羽生田栄一,水島宏太,長尾高弘
- 出版社/メーカー: インプレス
- 発売日: 2016/09/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
しょうもないことについてもざっくりメモをとって本が無くても見てわかるようなものにする&知識の定着が目的である。
Scalaのコレクションのimutableとmutable
Scalaのコレクションも他の言語と同様に基本のコレクションとして以下がある。(もちろん他にもある)
- Array,List
- tuple
- Set -Map
全てのコレクションの体系は参考にURLに詳しく記載があるため確認すると良い。
以前の記事で、Scalaは命令型と関数型の両方を使用できる言語だと説明したが、それを両立させるための手段として各コレクションにおいて「imutable」(不変)と「mutable」(可変)なものを持っている。
(正確にはそれらの基底クラスとなるscala.collection
も持っているが、おそらくこれを使うケースはあまりないのでは?と思う。)
そしてScalaでは関数型を推奨していることもあり、デフォルトで使用するコレクションは基本的に「imutable」となる。例えばmutableなものを使用したいときは以下のように明示的にimportしてあげる必要がある。
import scala.collection.mutable
早速以下で簡単にScalaのコレクションの使用方法について見ていこう。
配列(ArrayとList)
ちょっと最初私も混乱した点として、ArrayとListの存在がある。 これらは先に述べた「imutable」と「mutable」なコレクションを別の名前のコレクションとして保持している。 Array=mutableでList=imutableである。 なぜ別の名称がついているのが私はまだわかっていないが、おそらく本質的に異なるコレクションなのだと思う。(だとすると上記の説明では語弊があるかもしれない。 しかし、基本の使い方には大きな差異はないので、基本的な使用の仕方では強く意識する必要はなさそうだ。各スタイル、つまり関数型ならList、命令型ならArrayというように使い分ければいいだろう。
宣言と初期化
- new キーワードを使った配列の宣言 初期化しない宣言はmutableなコレクションしかできないため、Array専用の宣言方法となる。(List)は以降のnewキーワードを使用しない宣言で行う。
//固定長(長さ3)の配列 val fixedLengthList = new Array[String](3)
初期化をしたい場合、こちらの書き方でも宣言が可能である。 Listの場合はこれによって宣言を行う必要がある。
val initializedArray = Array("value1" ,"value2") val initializedList = List("value1", "value2")
基本的には型推論があるため不要だが、型を明示するときは以下のようにする。
val initializedArray :Array[String] = Array("value1", "value2") val initializedList :List[String] = List("value1", "value2")
要素の参照(呼び出し)
要素の呼び出しはJavaとは違い、()
による呼び出しを行う。
>> ArrayTest.scala val testArray = Array("test", "name") println(testArray(1))
ちなみにリストの場合も同様に以下で呼び出せる。
val testList = List("test", "name") println(testList(1))
ここでprintln()
とprint()
の違いは、前者は末尾に改行が付き、後者はつかないという違いがある。
実行すると以下の結果が得られる。
$ scala ArrayTest.scala name
ちなみに先程述べた、
要素の呼び出しはJavaとは違い、
()
による呼び出しを行う。
これはScalaの性質上重要な意味があるため別記事にてまとめる。
tuple(タプル)
tupleもimutableなオブジェクトであるがリストとは明確に異なる点がある。 それは要素に異なるデータ型を混在させることができる点である。
実はListも異なるデータ型を混在させて定義させることはできるのだが、この場合型推論ではList[any]として推論する。 書籍で上記の説明をしているのは
any
とすることを問題としてのことなのかはわかっていない。
宣言
tupleの宣言は簡単で、()
内で,
で区切ることで宣言ができる。
val testTuple = ("value" , 100)
値の参照(呼び出し)
tupleのややこしいところは、インデックスが1オリジンであることである。 (Haskell等の定義を受け継いでいるらしい)
val exTuple = ("value" , 100) println(exTuple._1) println(exTuple._2)
実行結果
$ scala TupleTest.scala value 100
Set(集合)
宣言
Setに関しては冒頭で説明したとおり、imutableがデフォルトでmutableなSetに関してはimportして使用する必要がある。
//imutableなSet val exSet = Set("value1", "value2") //mutableなSet import scala.collection.mutable val mutableSet = mutable.Set("value1", "value2") // 要素の追加が可能 mutableSet += "value3"
値の参照(呼び出し)
Setは内部の要素を指定して呼び出すようなメソッドを持っていない。
集合としての用途として.contains()
等使用する。
>>ExSet.scala val exSet = Set("value1", "value2") println(exSet) println(exSet.contains("value3") val mutableSet = mutable.Set("value1", "value2") mutableSet += "value3" println (mutableSet) println(mutableSet.contains("value3"))
実行結果
scala exSet.scala Set(value1, value2) false HashSet(value2, value1, value3) true
map(マップ)
宣言
mapもset同様mutableはimportして使用する。 imutableなmapは初期化で値を宣言する。
// imutableなmap val exMap = Map("name" -> "nooozui", "id" -> "ex") // mutableなmap import scala.collection.mutable val mutableMap = mutable.Map[String, String]() mutableMap += ("name" -> "nooozui") mutableMap += ("id" -> "ex")
値の参照(呼び出し)
mapは連想配列なので配列(array, list)と同様に(key)
で呼び出すことができる。
>>exMap val exMap = Map("name" -> "nooozui", "id" -> "ex") println(exMap("name")) println(exMap("id"))
実行結果
scala exMap.scala nooozui ex
終わりに
一通り宣言方法について学んだ。 Pythonを最初に使い始めた自分にとってはArray等の区別の違い等に混乱する部分が多かったので、今回の勉強で基本は整理できたと思う。 実際にはこれら様々な協力なメソッドが存在するのでそれらも別途まとめていきたい。