Scalaの基本を学ぶ【その1】〜制御構文・クラス・オブジェクト・関数〜
Scalaの基本を網羅!if式・match式・クラス・トレイト・関数などをサンプルコード付きで解説。初心者にもわかりやすい構成で逆引きにも最適!
Scalaの基本を後から見直しやすいようにと思い要所要所まとめましたが、とても長い記事となっております。逆引きのように見てもらえると幸いです。
動作環境ScalaとはScalaの基本制御構文if式while式for式(flatMap・map・withFilter・foreachなどあるが、ここでは基本的な使い方)match式クラスフィールド定義抽象メンバー継承継承する目的オブジェクトトレイトトレイトの基本菱形継承問題を解決するための線形化(linearization)自分型落とし穴:トレイトの初期化順序トレイトのvalの初期化順序の回避方法型パラメータと変位指定共変(covariant)関数無名関数関数のカリー化続きはその2へ!
動作環境
Scala:2.12
Scalaとは
- オブジェクト指向プログラミングと関数型プログラミングの統合
- Javaと互換性があり、ライブラリも使用可能
Scalaの基本
- 変数には、との2種類がある
- は値の再代入が不可。は値の再代入が可能。基本的にはのみでプログラミングする
- Swiftでいうところの、(再代入不可)と(再代入可能)
制御構文
if式
while式
for式(・・・などあるが、ここでは基本的な使い方)
for式の例:
- は1から5まで(5を含む)の範囲
- は1から5まで(5を含まない)の範囲
を使ったfor式の例:
- 構文はキーワードを使うことで、コレクションの要素を加工して返すという全く異なる要素に使うことが可能
match式
- 漏れがないようにするために、パターンにワイルドカード(など)を使用することも可能
クラス
フィールド定義
※ を付けたフィールドへのアクセスは一般にJVMレベルでのフィールドへの直接アクセスになるため、若干高速
抽象メンバー
その時点では実装を書くことができず、後述する継承の際に、メソッド・フィールドの実装を与えたいという時に、抽象メンバーを定義する。
抽象メンバーのメソッド実装例:
抽象メンバーのフィールド実装例:
継承
継承する目的
- スーパークラスの実装をサブクラスでも使うことで実装を再利用すること
- 複数のサブクラスが共通のスーパークラスのインターフェースを継承することで処理を共通化すること(サブタイピング・ポリモーフィズムと呼ぶ)
- Scalaでは、トレイトという仕組みで複数の実装の継承を実現している。(下記のトレイトを参照)
クラスの継承:
オブジェクト
- Scalaでは、全ての値がオブジェクトで、全てのメソッドは何らかのオブジェクトに所属している
構文の主な用途
- ユーティリティメソッドやグローバルな状態の置き場所
- オブジェクトのファクトリメソッド
- Singletonパターン
の基本構文:
- クラスと同じファイル内、同じ名前で定義されたシングルトンオブジェクトは、コンパニオンオブジェクトと呼ばれる
- コンパニオンオブジェクトは、対応するクラスに対して特権的なアクセス権を持つ
トレイト
- Scalaのトレイトはクラスからコンストラクタを定義する機能を抜いたようなもの
トレイトの定義:
トレイトの基本
クラスに比べて以下のような特徴がある
- 複数のトレイトを1つのクラスやトレイトにミックスインできる
- 複数のクラスを継承させたい場合は、クラスをトレイトにする必要がある
- 直接インスタンス化できない
- トレントを使うときは通常、それを継承したクラスを作る。これは、トレントが単体で使われることを想定していないための制限である。
- クラスパラメータ(コンストラクタの引数)を取ることができない
- トレイトに抽象メンバを持たせることで値を渡すことが可能
菱形継承問題を解決するための線形化(linearization)
継承関係が複雑になったメソッドを全て明示的に呼ぶのは大変であるため、トレイトがミックスインされた順番をトレイトの継承順番とみなす線形化という機能がある。
実行文:
トレイトの継承順番が線形化され、後からミックスインしたが優先されているため、のメソッドの呼び出しでのメソッドが実行されている。
自分型
- 自分型を使う場合、抽象トレイトを指定し、後から実装を追加するという形になる
- このように後(または外)から利用するモジュールの実装を与えることを「依存性の注入」と呼ぶ
- 型の循環参照(相互参照)を許す
落とし穴:トレイトの初期化順序
実行文:
Scalaのクラス・トレントはスーバークラスから順番に初期化される。
そのため、この例では、クラスはトレイトを継承し、トレイトはトレイトを継承している。
つまり、初期化はトレイトが一番先に行われ変数が宣言され、中身は何も代入していないので、nullになる。
次に、トレントで変数が宣言され、であると"World"という文字列からという文字列が作られ、変数に代入される。
トレイトのの初期化順序の回避方法
実行文:
の初期化にを使うことで、の初期化が実際に行われるまで遅延されることがなくなる。
型パラメータと変位指定
Scalaでは、何も指定しなかった型パラメータは通常は非変(invariant)になる。
共変(covariant)
配列型はJavaでは共変
- covariant.java
このJavaのコードはコンパイルは通るが、実行すると、が発生する。これは、に入っているのが、実際には、の配列(のみを要素として持つ)なのに、2行目で型(ボクシング変換されて)の値であるを渡そうとしていることになる。
配列型はScalaでは非変なので、上記のコードをコンパイルするとその時点でエラーが表示される。
関数
Scalaの関数は、単に 〜 までのトレントの無名サブクラスのインスタンスである。
2つの関数を取って加算した値を返す関数の定義例)
無名関数
先ほどのように関数定義するとコードが冗長になり過ぎる。そのため、Scalaでは、 〜 までのトレントのインスタンスを生成するためのシンタックスシュガーが用意されている。
シンタックスシュガーを使って関数を定義した例:
実行例:
関数のカリー化
カリー化とは、型の関数のように複数の引数を取る関数があったとき、これを型の関数のように1つの引数を取り、残りの引数を取る関数を返す関数のチェインで表現するというもの。
上記のをカリー化した関数を定義した例:
実行例:
続きはその2へ!
Scalaの基本を学ぶ【その2】〜コレクション・リスト・マップ・セットの使い方〜2024/6/5 23:272025/3/4 0:40
小幡 十矛(Obata Tomu)|価値を共創するエンジニア
東京を拠点に、アプリ開発・新規事業立ち上げ・ブランドづくりに取り組んでいます。
2021年にサイバーエージェントへ新卒入社後、ABEMA Live や AmebaブログのiOSアプリ開発を担当。
現在はフリーランスとして、複数の新規プロダクトやリアル店舗の立ち上げに挑戦中です。
🎯 Mission|人の挑戦を加速する仕組みをつくる
── アイデアを形にし、前に進める“土台”や“場”を共創する
📌 「リアルな場 × デジタル」の可能性を探求し、新しい挑戦が生まれる土壌を育てる
🔹 エンジニアリング × ビジネスの視点から、アイデアを形にし、成長を支えていく
🔹 実店舗オーナーを目指し、オーダースーツ・ドライヘッドスパ・セレクトショップの複合店舗の立ち上げにも挑戦中
👥 特に、社会人1〜5年目くらいで
「やりたい気持ちはあるけど、最初の一歩に迷っている」方へ。
「自分の可能性をもっと広げたい」
「モヤっとしたアイデアがあるけど、どう進めていいかわからない」
そんなフェーズにいる方と、一緒に考えたり、手を動かしたりできたら嬉しいです。
🌱 「挑戦したい20代」との出会いも、大切にしています。
「ちょっと話してみたいな」くらいの気持ちで、気軽に声をかけてもらえたら嬉しいです!🙌
🌐 詳しいプロフィールはこちら
https://obata-tomu.jp/