狠狠撸

狠狠撸Share a Scribd company logo
(bitly url)
おことわり
Scala関西 Summit 2017でamayaさ
んによって行なわれた講演の再演で
す
Scalaをはじめよう! ─マルチパラ
ダイム言語への招待─
https://nextpublishing.jp/book/9497.ht
ml
2018-11-10ゼロから始めるScalaプロジェクト
2
参考サイトたち
ひしだま's 技術メモ Scala
http://www.ne.jp/asahi/hishidama/home/tech/scala/index.html
網羅的
Scala Text (ドワンゴ社による研修資料)
https://dwango.github.io/scala_text/
言語学的な部分?実務まで
Scala公式ドキュメント
http://docs.scala-lang.org /
最近整備された
Scala Standard Library API
http://www.scala-lang.org/api/current/index.html
Google先生が苦手な記号でも検索できる
2018-11-10ゼロから始めるScalaプロジェクト
3
What's Scala?
「Scalable Language」
「オブジェクト指向」?「関数型」両方の特性を持つ強い静的型
付け言語
強い静的型付け言語だが, コンパイラの補助が強力?コードが簡潔
実態は「関数型由来の便利ツールを利用できるオブジェクト指向型言
語」
ちょっとしたスクリプト?大規模分散環境まで広く適用可能
JVMで動作
Javaのライブラリ資産も利用可能, Javaコードと併用可能
最近は ネイティブ (LLVM)/JavaScript でも結構動く
sbtがビルドツールのデファクトスタンダード
これだけ入れておけばok
オーバーヘッドな
し
scala コマンドは不
要
2018-11-10ゼロから始めるScalaプロジェクト
4
Scalaの良いところ
構文や標準ライブラリが洗練されており,
処理を簡潔に書ける
? Java
配列とリストを同じように扱いたいのに配列だけ構文が違う…
統一的に扱えます
変数宣言のシグネチャが冗長…
コンパイラの型推論におまかせ
デフォルト引数?名前付き引数が…
あります
Thread/ExecutorService面倒…
非同期処理に便利なやつが標準ライブラリにあります
? Light-weight Language
ランタイムエラーが怖い…
型はある種のテスト
2018-11-10ゼロから始めるScalaプロジェクト
5
Scalaの悪いところ
コンパイルが遅い?
よく勘違いされるポイント
初めてコンパイルして遅すぎて投げた
→ 初回はScala本体や依存解決のダウンロードがあるため特別遅い
コンパイルの度にsbtを起動している
→ JVM起動の時間があるため. sbtは立ち上げっぱなしにしておく
それでも比較的遅い…アップデートで改善されつつある
表現力が高いが故に, 同じ処理に様々な実現方法があ
る
「一つの処理に唯一の記述方法を」としているPythonの対極
特に, 個々では便利な糖衣構文が複数合わさると
全く異なる見た目になってしまう
2018-11-10ゼロから始めるScalaプロジェクト
6
Scalaで意識すべきこと
(関数型もできるが) 基本はオブジェクト指向
出来る限り不変な値を使う
以上
2018-11-10ゼロから始めるScalaプロジェクト
7
Hello World!
object Main {
def main(args: Array[String]): Unit =
{
val message1 = "Hello"
var message2 = "World"
message2 += "!"
println(message1 + " " + message2)
}
}
エントリポイン
ト
メソッド
再代入可変数
改行付標準出力
再代入不可変数
型は推論される
2018-11-10ゼロから始めるScalaプロジェクト
8
Hello World!
def main(args: Array[String]): Unit = {
val message1 = "Hello"
var message2 = "World"
message2 += "!"
println(message1 + " " + message2)
}
仮引数 仮引数の型
「文字列」の「配
列」
[] は多相の記号
返り値の型
Unit は返り値が
無いことを意味する
型
(≒void)
式: 計算が行われ, 必ず値を返す
returnは不要
2018-11-10ゼロから始めるScalaプロジェクト
9
Hello World!
{
val message1 = "Hello"
var message2 = "World"
message2 += "!"
println(message1 + " " + message2)
}
ブロック式
順
番
に
評
価
最後に評価された式の返り値が
ブロック式全体の返り値になる
println の
返り値は Unit型
式や文
2018-11-10ゼロから始めるScalaプロジェクト
10
Hello World!
def twice(x: Int): Int = {
x * 2
}
def twice(x: Int): Int = x * 2
式式
{} はあくまでブロック式
メソッド宣言とは無関係
2018-11-10ゼロから始めるScalaプロジェクト
11
式と文
val result = {
val x = 1 + 2
if (x < 0) x else x * 2
}
ブロック式
順
番
に
評
価
最後に評価された式の返り値が
ブロック式全体の返り値になる
最後に評価された式の返り値が
ブロック式全体の返り値になる
6: Int
resultには
6が代入される
if式
(≒3項演算子)
2018-11-10ゼロから始めるScalaプロジェクト
12
代入文
式と文
val result = {
val x = 1 + 2
if (x < 0) x else x * 2
}
式
文
2018-11-10ゼロから始めるScalaプロジェクト
13
for式 (ループもできる)
for {i <- 1 to 3} {
println(i)
}
for {i <- 1 to 3} println(i)
val results = for {i <- 1 to 3} i
ブロック式
式式
ジェネレータ 1,2,3 から成る数値列の生成
このままでは値を返さな
い
(): Unit
2018-11-10ゼロから始めるScalaプロジェクト
14
for式
val results1 = for {i <- 1 to 3} yield i
val results2 = for {
i <- 1 to 5 by 2
j <- 2 to 1 by -1
} yield {
val x = i * j
x + 1
}
yield を付けると値を返す1,2,3
1,3,5
2,1
3,2,7,4,11,6
ジェネレータを
複数並べること
で
多重ループ
ループに再代入可能な変数は不
要
to: <=, until: <, by: += n
2018-11-10ゼロから始めるScalaプロジェクト
15
match式
val n = 2
val result = n match {
case 1 =>
"1"
case 2 | 3 =>
"2 or 3"
case x if x % 2 == 0 =>
"偶数の" + x.toString
case x =>
s"それ以外の${x}"
}上記以外にも
様々な条件を指定可能
対象
定数による条件
OR条件
全てにマッチす
るx
+ 偶数である
全てにマッチする
x
"2 or 3"
順
番
に
評
価
最初にマッチした
箇所のみ実行され
る
(break不要)
2018-11-10ゼロから始めるScalaプロジェクト
16
match式
val n = 5
val result = n match {
case 1 =>
"1"
case 2 | 3 =>
"2 or 3"
case x if x % 2 == 0 =>
"偶数の" + x.toString
case x =>
s"それ以外の${x}"
}上記以外にも
様々な条件を指定可能
対象
定数による条件
OR条件
全てにマッチす
るx
+ 偶数である
全てにマッチする
x
"それ以外の5"
順
番
に
評
価
文字列化
式を埋め込み可能な文字列式を埋め込み可能な文字列
2018-11-10ゼロから始めるScalaプロジェクト
17
クラス?オブジェクト?トレイト
class Triangle(edges: Array[Int]) {
val area = ??? // 省略
def printFigure(): Unit = println("△")
}
val triangle = new Triangle(Array(3, 4, 5))
println(triangle.area)
コンストラクタ引数リ
スト
フィールドそのもの
が
コンストラクタにな
るインスタンス
化
6.0 ??? は未実装例外のエイリアス
仮にコンパイルを通すのに便利
2018-11-10ゼロから始めるScalaプロジェクト
18
クラス?オブジェクト?トレイト
abstract class Polygon(edges: Array[Int]) {
val n = edges.size
val area: Double
def printFigure(): Unit
}
class Triangle(edges: Array[Int]) extends Polygon(edges)
{
val area = ??? // 省略
def printFigure(): Unit = println("△")
}
val triangle = new Triangle(Array(3, 4, 5))
println(triangle.area)
抽象クラ
ス
継承
2018-11-10ゼロから始めるScalaプロジェクト
19
+α
クラス?オブジェクト?トレイト
abstract class Polygon private(edges: Array[Int]) {
val n = edges.size
val area: Double
def printFigure(): Unit
}
object Polygon {
def fromEdges(edges: Array[Int]): Polygon =
edges.size match {
case 3 => new Triangle(edges)
case 4 => new Square(edges)
case n => ???
}
}
Polygon.fromEdges(Array(3, 4, 5))
オブジェクト (≒staticフィール
ド)
Triengle
同名のクラスが同一ファイル
にあるオブジェクトを
コンパニオンオブジェクトと
呼ぶ
privateにアクセスできる
privateコンストラクタ
2018-11-10ゼロから始めるScalaプロジェクト
20
+α
クラス?オブジェクト?トレイト
import java.util.Date
trait Tag {
val createdDate: Date
}
trait Color {
val rgb: RGB
}
class TaggedGreenTriangle
extends Triangle with Tag with Color {
val rbg = new RGB(0, 255, 0)
val createdDate = new Date
}
トレイト: 多重継承可, コンストラクタ引数
なし
抽象クラスに似ている
が
一部機能が異なる.
どちらも利用できて
迷ったらトレイト
インポート (クラス, オブジェクト, メソッ
ド等)
別名ミックスイ
ン
2つ目以降は with で繋ぐ
2018-11-10ゼロから始めるScalaプロジェクト
21
コレクション?関数
val list1 = (1 to 3).toList
val list2 = List(1, 2, 3)
val array = Array(1, 2, 3)
val odds1 = list1.filter(x => x % 2 == 1)
val odds2 = array.filter(x => x % 2 == 1)
val sum = list1.sum
val twice = list1.map(x => x * 2)
val sorted = list1.sorted
Range: 範囲から生成されるコレクショ
ン
同一I/F
List (単方向) に変換
直接 List の初期化
Array (中身はJava配列)
多様な便利API
1,2,31,2,31,2,3
1,31,3
6
2,4,6
1,2,3
2018-11-10ゼロから始めるScalaプロジェクト
22
コレクション?関数
val list = (1 to 3).toList
val odds1 = list.filter(x => x % 2 == 1)
val selectOdd: Int => Boolean = x => x % 2 == 1
val odds2 = list.filter(selectOdd)
匿名関数のラムダ記
法
匿名関数のラムダ記
法
仮引数仮引数 式式要シグネチャ
filterは (T => Boolean) 型を引数に取り各要素で実行
: List[Int]
T が Int
デフォルトは不変コレクション (Arrayは例
外)
import scala.collection.mutable.XXX
で可変コレクションも利用可能
2018-11-10ゼロから始めるScalaプロジェクト
23
エラーハンドリング
def getData(q: Query): Option[String] = ???
getData(q) match {
case Some(str) => println(str)
case None => println("該当なし")
}
Option[T]
抽象クラス
Some[T]
単一値を保持
None
値なし
必ずどちらか必ずどちらか
match式で場合分け兼Someの場合は値の取り出し
2018-11-10ゼロから始めるScalaプロジェクト
24
データの利用者に
データのチェックを強制させる
エラーハンドリング
def getNullableString(): String = ??? // 省略
val stringOpt = Option(getNullableString())
stringOpt match {
case Some(str) => println(str)
case None => println("nullでした")
}
def throwableMethod(): Int = ??? // 省略
val result = try {
throwableMethod()
} catch {
case ex: Throwable => 0
}
try式
式: ブロック
式
match式のように
例外で場合分け式
nullならNone,
それ以外ならSome
を返す便利メソッド
値な
し
単一
値
2018-11-10ゼロから始めるScalaプロジェクト
25
(実際は返り値をOptionにすると良い)
+α
エラーハンドリング
val list = (1 to 3).toList
list.foreach(x => println(x))
def getNullableString(): String = ??? // 省略
val stringOpt = Option(getNullableString())
stringOpt.foreach(str => println(str))
(T => Unit) 型を引数に取り各要素で実行 T が Int
コレクションと同じAPIも利用可
能
Noneは長さ0, Someは長さ1の
コレクションのように振る舞う
似たようなものとして, 文字列も文字
の
コレクションとして扱うことが可能
2018-11-10ゼロから始めるScalaプロジェクト
26
+α
2018-11-10ゼロから始めるScalaプロジェクト
27
+α
糖衣構文
val x1 = 1 + 2
val x2 = 1.+(2)
implicit class MyInt(val x: Int) extends AnyVal {
def add(another: Int): Int = x + another
}
val y1 = 1.add(2)
val y2 = 1 add 2
数値を1つ引数に取るIntのメソッ
ド
Intに「数値を1つ引数に取るメソッ
ド」
であるaddを追加 (※詳細省略)
2018-11-10ゼロから始めるScalaプロジェクト
28
等しい
等しい
「引数を1つ取るメソッド」の呼び出
しは
「.」と「()」を省略できる
+α
糖衣構文
class Cat(cry: String) {
def apply(postfix: String): Unit =
println(cry + postfix)
}
object Cat {
def apply(cry: String): Cat = new Cat(cry)
}
val cat1 = new Cat("にゃー")
val cat2 = Cat("にゃー")
val cat3 = Cat.apply("にゃー")
cat1("!")
cat1.apply("!")
「apply」という名前であればなんでもよ
い
2018-11-10ゼロから始めるScalaプロジェクト
29
等しい
「applyという名前のメソッド」の呼び出
しは
「.apply」を省略できる
等しい
配列やリストのインデックス参照が
「()」
でできるのはapplyによるもの
+α
クラス
class Cat(cry: String)
val cat = new Cat("にゃー")
// cryはprivateなので外部からアクセスできない
class Cat(val cry: String)
val cat = new Cat("にゃー")
// 宣言にvalを付けると外部からアクセスできる
println(cat.cry)
2018-11-10ゼロから始めるScalaプロジェクト
30
publicになる
デフォルトはprivate
varだと更に
再代入可能に
+α
ケースクラス
case class Cat(cry: String)
val cat1 = new Cat("にゃー")
val cat2 = Cat("にゃー")
val cat3 = Cat.apply("にゃー")
println(cat1.cry)
println(cat1.toString)
getData(q) match {
case Some(str) => println(str)
case None => println("該当なし")
}
2018-11-10ゼロから始めるScalaプロジェクト
31
コンストラクタ引数と
等しい引数を持つapplyが
自動的に定義されるため,
見かけ上newが不要になる
caseを付けるだけ
デフォルトでpublic
いい感じのtoString
コンストラクタ引数
で
パターンマッチ可能
unapply
(※詳細省略)
通常のclassに便利機能が自動定義される
+α
Ad

Recommended

Scala の関数型フ?ロク?ラミンク?を支える技術
Scala の関数型フ?ロク?ラミンク?を支える技術
Naoki Aoyama
?
厂肠补濒补东北绍介
厂肠补濒补东北绍介
Takeda Hiroyuki
?
2013-12-08 西区プログラム勉強会
2013-12-08 西区プログラム勉強会
Takatoshi Murakami
?
闯补惫补8から始める関数型フ?ロク?ラミンク?
闯补惫补8から始める関数型フ?ロク?ラミンク?
stylefreeslide
?
Phantom Type in Scala
Phantom Type in Scala
Yasuyuki Maeda
?
闯补惫补の骋别苍别谤颈肠蝉とは?
闯补惫补の骋别苍别谤颈肠蝉とは?
Kenji Nakamura
?
Introduction Xtend
Introduction Xtend
Hideki Kishida
?
プログラミング言语厂肠补濒补
プログラミング言语厂肠补濒补
TanUkkii
?
厂肠补濒补による型安全なエラーハント?リンク?
厂肠补濒补による型安全なエラーハント?リンク?
TanUkkii
?
ラムダ计算入门
ラムダ计算入门
Eita Sugimoto
?
C#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to Objects
Fumitaka Yamada
?
厂肠补濒补で型クラス入门
厂肠补濒补で型クラス入门
Makoto Fukuhara
?
関数プログラミング入门
関数プログラミング入门
Hideyuki Tanaka
?
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎と クラス設計への応用
nagise
?
プログラミング贬补蝉办别濒濒(第1章)
プログラミング贬补蝉办别濒濒(第1章)
yaju88
?
Haskell勉強会 in ie
Haskell勉強会 in ie
maeken2010
?
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
koji lin
?
纯粋関数型アルゴリズム入门
纯粋関数型アルゴリズム入门
Kimikazu Kato
?
プログラミング贬补蝉办别濒濒(第2章)
プログラミング贬补蝉办别濒濒(第2章)
yaju88
?
プログラミング言语のパラダイムシフトー厂肠补濒补から见る関数型と并列性时代の幕开けー
プログラミング言语のパラダイムシフトー厂肠补濒补から见る関数型と并列性时代の幕开けー
TanUkkii
?
厂肠补濒补2.8への移行
厂肠补濒补2.8への移行
guest5f4320
?
(Lambdaだけで) 純LISPのような ナニかを作る
(Lambdaだけで) 純LISPのような ナニかを作る
Daichi Teruya
?
Project lambda
Project lambda
Appresso Engineering Team
?
Livesense tech night immutable-js at a glance
Livesense tech night immutable-js at a glance
Yuta Shimakawa
?
尝颈蝉辫讲义1
尝颈蝉辫讲义1
stibear (stibear1996)
?
Beginners Scala in FAN 20121009
Beginners Scala in FAN 20121009
Taisuke Shiratori
?
厂肠补濒补で萌える関数型プログラミング摆完全版闭
厂肠补濒补で萌える関数型プログラミング摆完全版闭
Ra Zon
?

More Related Content

What's hot (20)

プログラミング言语厂肠补濒补
プログラミング言语厂肠补濒补
TanUkkii
?
厂肠补濒补による型安全なエラーハント?リンク?
厂肠补濒补による型安全なエラーハント?リンク?
TanUkkii
?
ラムダ计算入门
ラムダ计算入门
Eita Sugimoto
?
C#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to Objects
Fumitaka Yamada
?
厂肠补濒补で型クラス入门
厂肠补濒补で型クラス入门
Makoto Fukuhara
?
関数プログラミング入门
関数プログラミング入门
Hideyuki Tanaka
?
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎と クラス設計への応用
nagise
?
プログラミング贬补蝉办别濒濒(第1章)
プログラミング贬补蝉办别濒濒(第1章)
yaju88
?
Haskell勉強会 in ie
Haskell勉強会 in ie
maeken2010
?
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
koji lin
?
纯粋関数型アルゴリズム入门
纯粋関数型アルゴリズム入门
Kimikazu Kato
?
プログラミング贬补蝉办别濒濒(第2章)
プログラミング贬补蝉办别濒濒(第2章)
yaju88
?
プログラミング言语のパラダイムシフトー厂肠补濒补から见る関数型と并列性时代の幕开けー
プログラミング言语のパラダイムシフトー厂肠补濒补から见る関数型と并列性时代の幕开けー
TanUkkii
?
厂肠补濒补2.8への移行
厂肠补濒补2.8への移行
guest5f4320
?
(Lambdaだけで) 純LISPのような ナニかを作る
(Lambdaだけで) 純LISPのような ナニかを作る
Daichi Teruya
?
Project lambda
Project lambda
Appresso Engineering Team
?
Livesense tech night immutable-js at a glance
Livesense tech night immutable-js at a glance
Yuta Shimakawa
?
尝颈蝉辫讲义1
尝颈蝉辫讲义1
stibear (stibear1996)
?
プログラミング言语厂肠补濒补
プログラミング言语厂肠补濒补
TanUkkii
?
厂肠补濒补による型安全なエラーハント?リンク?
厂肠补濒补による型安全なエラーハント?リンク?
TanUkkii
?
C#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to Objects
Fumitaka Yamada
?
厂肠补濒补で型クラス入门
厂肠补濒补で型クラス入门
Makoto Fukuhara
?
関数プログラミング入门
関数プログラミング入门
Hideyuki Tanaka
?
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎と クラス設計への応用
nagise
?
プログラミング贬补蝉办别濒濒(第1章)
プログラミング贬补蝉办别濒濒(第1章)
yaju88
?
Haskell勉強会 in ie
Haskell勉強会 in ie
maeken2010
?
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
koji lin
?
纯粋関数型アルゴリズム入门
纯粋関数型アルゴリズム入门
Kimikazu Kato
?
プログラミング贬补蝉办别濒濒(第2章)
プログラミング贬补蝉办别濒濒(第2章)
yaju88
?
プログラミング言语のパラダイムシフトー厂肠补濒补から见る関数型と并列性时代の幕开けー
プログラミング言语のパラダイムシフトー厂肠补濒补から见る関数型と并列性时代の幕开けー
TanUkkii
?
厂肠补濒补2.8への移行
厂肠补濒补2.8への移行
guest5f4320
?
(Lambdaだけで) 純LISPのような ナニかを作る
(Lambdaだけで) 純LISPのような ナニかを作る
Daichi Teruya
?
Livesense tech night immutable-js at a glance
Livesense tech night immutable-js at a glance
Yuta Shimakawa
?

Similar to ゼロから始めるScala文法 (再) (20)

Beginners Scala in FAN 20121009
Beginners Scala in FAN 20121009
Taisuke Shiratori
?
厂肠补濒补で萌える関数型プログラミング摆完全版闭
厂肠补濒补で萌える関数型プログラミング摆完全版闭
Ra Zon
?
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
Ra Zon
?
厂肠补濒补プログラミング?マニアックス
厂肠补濒补プログラミング?マニアックス
Tomoharu ASAMI
?
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
Naoki Kitora
?
15分でざっくり分かる厂肠补濒补入门
15分でざっくり分かる厂肠补濒补入门
SatoYu1ro
?
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
Ouka Yuka
?
From Scala/Clojure to Kotlin
From Scala/Clojure to Kotlin
Kent Ohashi
?
厂肠补濒补勉强会冲2014冲11冲18
厂肠补濒补勉强会冲2014冲11冲18
Shuya Tsukamoto
?
実务者のためのかんたん厂肠补濒补锄
実务者のためのかんたん厂肠补濒补锄
Tomoharu ASAMI
?
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
Takuya Tsuchida
?
20121222 scalaビギナーズ
20121222 scalaビギナーズ
Asami Abe
?
第2回関数型言語勉強会 大阪
第2回関数型言語勉強会 大阪
Naoki Kitora
?
関数プログラミングことはじめ
関数プログラミングことはじめ
Naoki Kitora
?
明日から业务て?使う厂肠补濒补
明日から业务て?使う厂肠补濒补
martin_lover_ca
?
Object-Funcational Analysis and design
Object-Funcational Analysis and design
Tomoharu ASAMI
?
Scala超入門 - 2014/12/13 Scala関西勉強会
Scala超入門 - 2014/12/13 Scala関西勉強会
Asami Abe
?
たのしい関数型
たのしい関数型
Shinichi Kozake
?
Beginners Scala in FAN 20121009
Beginners Scala in FAN 20121009
Taisuke Shiratori
?
厂肠补濒补で萌える関数型プログラミング摆完全版闭
厂肠补濒补で萌える関数型プログラミング摆完全版闭
Ra Zon
?
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
厂肠补濒补で萌える関数型プログラミング摆1.1.搁颁1闭
Ra Zon
?
厂肠补濒补プログラミング?マニアックス
厂肠补濒补プログラミング?マニアックス
Tomoharu ASAMI
?
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
命令フ?ロク?ラミンク?から関数フ?ロク?ラミンク?へ
Naoki Kitora
?
15分でざっくり分かる厂肠补濒补入门
15分でざっくり分かる厂肠补濒补入门
SatoYu1ro
?
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
Ouka Yuka
?
From Scala/Clojure to Kotlin
From Scala/Clojure to Kotlin
Kent Ohashi
?
厂肠补濒补勉强会冲2014冲11冲18
厂肠补濒补勉强会冲2014冲11冲18
Shuya Tsukamoto
?
実务者のためのかんたん厂肠补濒补锄
実务者のためのかんたん厂肠补濒补锄
Tomoharu ASAMI
?
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
Takuya Tsuchida
?
20121222 scalaビギナーズ
20121222 scalaビギナーズ
Asami Abe
?
第2回関数型言語勉強会 大阪
第2回関数型言語勉強会 大阪
Naoki Kitora
?
関数プログラミングことはじめ
関数プログラミングことはじめ
Naoki Kitora
?
明日から业务て?使う厂肠补濒补
明日から业务て?使う厂肠补濒补
martin_lover_ca
?
Object-Funcational Analysis and design
Object-Funcational Analysis and design
Tomoharu ASAMI
?
Scala超入門 - 2014/12/13 Scala関西勉強会
Scala超入門 - 2014/12/13 Scala関西勉強会
Asami Abe
?
Ad

ゼロから始めるScala文法 (再)

  • 2. おことわり Scala関西 Summit 2017でamayaさ んによって行なわれた講演の再演で す Scalaをはじめよう! ─マルチパラ ダイム言語への招待─ https://nextpublishing.jp/book/9497.ht ml 2018-11-10ゼロから始めるScalaプロジェクト 2
  • 3. 参考サイトたち ひしだま's 技術メモ Scala http://www.ne.jp/asahi/hishidama/home/tech/scala/index.html 網羅的 Scala Text (ドワンゴ社による研修資料) https://dwango.github.io/scala_text/ 言語学的な部分?実務まで Scala公式ドキュメント http://docs.scala-lang.org / 最近整備された Scala Standard Library API http://www.scala-lang.org/api/current/index.html Google先生が苦手な記号でも検索できる 2018-11-10ゼロから始めるScalaプロジェクト 3
  • 4. What's Scala? 「Scalable Language」 「オブジェクト指向」?「関数型」両方の特性を持つ強い静的型 付け言語 強い静的型付け言語だが, コンパイラの補助が強力?コードが簡潔 実態は「関数型由来の便利ツールを利用できるオブジェクト指向型言 語」 ちょっとしたスクリプト?大規模分散環境まで広く適用可能 JVMで動作 Javaのライブラリ資産も利用可能, Javaコードと併用可能 最近は ネイティブ (LLVM)/JavaScript でも結構動く sbtがビルドツールのデファクトスタンダード これだけ入れておけばok オーバーヘッドな し scala コマンドは不 要 2018-11-10ゼロから始めるScalaプロジェクト 4
  • 6. Scalaの悪いところ コンパイルが遅い? よく勘違いされるポイント 初めてコンパイルして遅すぎて投げた → 初回はScala本体や依存解決のダウンロードがあるため特別遅い コンパイルの度にsbtを起動している → JVM起動の時間があるため. sbtは立ち上げっぱなしにしておく それでも比較的遅い…アップデートで改善されつつある 表現力が高いが故に, 同じ処理に様々な実現方法があ る 「一つの処理に唯一の記述方法を」としているPythonの対極 特に, 個々では便利な糖衣構文が複数合わさると 全く異なる見た目になってしまう 2018-11-10ゼロから始めるScalaプロジェクト 6
  • 8. Hello World! object Main { def main(args: Array[String]): Unit = { val message1 = "Hello" var message2 = "World" message2 += "!" println(message1 + " " + message2) } } エントリポイン ト メソッド 再代入可変数 改行付標準出力 再代入不可変数 型は推論される 2018-11-10ゼロから始めるScalaプロジェクト 8
  • 9. Hello World! def main(args: Array[String]): Unit = { val message1 = "Hello" var message2 = "World" message2 += "!" println(message1 + " " + message2) } 仮引数 仮引数の型 「文字列」の「配 列」 [] は多相の記号 返り値の型 Unit は返り値が 無いことを意味する 型 (≒void) 式: 計算が行われ, 必ず値を返す returnは不要 2018-11-10ゼロから始めるScalaプロジェクト 9
  • 10. Hello World! { val message1 = "Hello" var message2 = "World" message2 += "!" println(message1 + " " + message2) } ブロック式 順 番 に 評 価 最後に評価された式の返り値が ブロック式全体の返り値になる println の 返り値は Unit型 式や文 2018-11-10ゼロから始めるScalaプロジェクト 10
  • 11. Hello World! def twice(x: Int): Int = { x * 2 } def twice(x: Int): Int = x * 2 式式 {} はあくまでブロック式 メソッド宣言とは無関係 2018-11-10ゼロから始めるScalaプロジェクト 11
  • 12. 式と文 val result = { val x = 1 + 2 if (x < 0) x else x * 2 } ブロック式 順 番 に 評 価 最後に評価された式の返り値が ブロック式全体の返り値になる 最後に評価された式の返り値が ブロック式全体の返り値になる 6: Int resultには 6が代入される if式 (≒3項演算子) 2018-11-10ゼロから始めるScalaプロジェクト 12 代入文
  • 13. 式と文 val result = { val x = 1 + 2 if (x < 0) x else x * 2 } 式 文 2018-11-10ゼロから始めるScalaプロジェクト 13
  • 14. for式 (ループもできる) for {i <- 1 to 3} { println(i) } for {i <- 1 to 3} println(i) val results = for {i <- 1 to 3} i ブロック式 式式 ジェネレータ 1,2,3 から成る数値列の生成 このままでは値を返さな い (): Unit 2018-11-10ゼロから始めるScalaプロジェクト 14
  • 15. for式 val results1 = for {i <- 1 to 3} yield i val results2 = for { i <- 1 to 5 by 2 j <- 2 to 1 by -1 } yield { val x = i * j x + 1 } yield を付けると値を返す1,2,3 1,3,5 2,1 3,2,7,4,11,6 ジェネレータを 複数並べること で 多重ループ ループに再代入可能な変数は不 要 to: <=, until: <, by: += n 2018-11-10ゼロから始めるScalaプロジェクト 15
  • 16. match式 val n = 2 val result = n match { case 1 => "1" case 2 | 3 => "2 or 3" case x if x % 2 == 0 => "偶数の" + x.toString case x => s"それ以外の${x}" }上記以外にも 様々な条件を指定可能 対象 定数による条件 OR条件 全てにマッチす るx + 偶数である 全てにマッチする x "2 or 3" 順 番 に 評 価 最初にマッチした 箇所のみ実行され る (break不要) 2018-11-10ゼロから始めるScalaプロジェクト 16
  • 17. match式 val n = 5 val result = n match { case 1 => "1" case 2 | 3 => "2 or 3" case x if x % 2 == 0 => "偶数の" + x.toString case x => s"それ以外の${x}" }上記以外にも 様々な条件を指定可能 対象 定数による条件 OR条件 全てにマッチす るx + 偶数である 全てにマッチする x "それ以外の5" 順 番 に 評 価 文字列化 式を埋め込み可能な文字列式を埋め込み可能な文字列 2018-11-10ゼロから始めるScalaプロジェクト 17
  • 18. クラス?オブジェクト?トレイト class Triangle(edges: Array[Int]) { val area = ??? // 省略 def printFigure(): Unit = println("△") } val triangle = new Triangle(Array(3, 4, 5)) println(triangle.area) コンストラクタ引数リ スト フィールドそのもの が コンストラクタにな るインスタンス 化 6.0 ??? は未実装例外のエイリアス 仮にコンパイルを通すのに便利 2018-11-10ゼロから始めるScalaプロジェクト 18
  • 19. クラス?オブジェクト?トレイト abstract class Polygon(edges: Array[Int]) { val n = edges.size val area: Double def printFigure(): Unit } class Triangle(edges: Array[Int]) extends Polygon(edges) { val area = ??? // 省略 def printFigure(): Unit = println("△") } val triangle = new Triangle(Array(3, 4, 5)) println(triangle.area) 抽象クラ ス 継承 2018-11-10ゼロから始めるScalaプロジェクト 19 +α
  • 20. クラス?オブジェクト?トレイト abstract class Polygon private(edges: Array[Int]) { val n = edges.size val area: Double def printFigure(): Unit } object Polygon { def fromEdges(edges: Array[Int]): Polygon = edges.size match { case 3 => new Triangle(edges) case 4 => new Square(edges) case n => ??? } } Polygon.fromEdges(Array(3, 4, 5)) オブジェクト (≒staticフィール ド) Triengle 同名のクラスが同一ファイル にあるオブジェクトを コンパニオンオブジェクトと 呼ぶ privateにアクセスできる privateコンストラクタ 2018-11-10ゼロから始めるScalaプロジェクト 20 +α
  • 21. クラス?オブジェクト?トレイト import java.util.Date trait Tag { val createdDate: Date } trait Color { val rgb: RGB } class TaggedGreenTriangle extends Triangle with Tag with Color { val rbg = new RGB(0, 255, 0) val createdDate = new Date } トレイト: 多重継承可, コンストラクタ引数 なし 抽象クラスに似ている が 一部機能が異なる. どちらも利用できて 迷ったらトレイト インポート (クラス, オブジェクト, メソッ ド等) 別名ミックスイ ン 2つ目以降は with で繋ぐ 2018-11-10ゼロから始めるScalaプロジェクト 21
  • 22. コレクション?関数 val list1 = (1 to 3).toList val list2 = List(1, 2, 3) val array = Array(1, 2, 3) val odds1 = list1.filter(x => x % 2 == 1) val odds2 = array.filter(x => x % 2 == 1) val sum = list1.sum val twice = list1.map(x => x * 2) val sorted = list1.sorted Range: 範囲から生成されるコレクショ ン 同一I/F List (単方向) に変換 直接 List の初期化 Array (中身はJava配列) 多様な便利API 1,2,31,2,31,2,3 1,31,3 6 2,4,6 1,2,3 2018-11-10ゼロから始めるScalaプロジェクト 22
  • 23. コレクション?関数 val list = (1 to 3).toList val odds1 = list.filter(x => x % 2 == 1) val selectOdd: Int => Boolean = x => x % 2 == 1 val odds2 = list.filter(selectOdd) 匿名関数のラムダ記 法 匿名関数のラムダ記 法 仮引数仮引数 式式要シグネチャ filterは (T => Boolean) 型を引数に取り各要素で実行 : List[Int] T が Int デフォルトは不変コレクション (Arrayは例 外) import scala.collection.mutable.XXX で可変コレクションも利用可能 2018-11-10ゼロから始めるScalaプロジェクト 23
  • 24. エラーハンドリング def getData(q: Query): Option[String] = ??? getData(q) match { case Some(str) => println(str) case None => println("該当なし") } Option[T] 抽象クラス Some[T] 単一値を保持 None 値なし 必ずどちらか必ずどちらか match式で場合分け兼Someの場合は値の取り出し 2018-11-10ゼロから始めるScalaプロジェクト 24 データの利用者に データのチェックを強制させる
  • 25. エラーハンドリング def getNullableString(): String = ??? // 省略 val stringOpt = Option(getNullableString()) stringOpt match { case Some(str) => println(str) case None => println("nullでした") } def throwableMethod(): Int = ??? // 省略 val result = try { throwableMethod() } catch { case ex: Throwable => 0 } try式 式: ブロック 式 match式のように 例外で場合分け式 nullならNone, それ以外ならSome を返す便利メソッド 値な し 単一 値 2018-11-10ゼロから始めるScalaプロジェクト 25 (実際は返り値をOptionにすると良い) +α
  • 26. エラーハンドリング val list = (1 to 3).toList list.foreach(x => println(x)) def getNullableString(): String = ??? // 省略 val stringOpt = Option(getNullableString()) stringOpt.foreach(str => println(str)) (T => Unit) 型を引数に取り各要素で実行 T が Int コレクションと同じAPIも利用可 能 Noneは長さ0, Someは長さ1の コレクションのように振る舞う 似たようなものとして, 文字列も文字 の コレクションとして扱うことが可能 2018-11-10ゼロから始めるScalaプロジェクト 26
  • 28. 糖衣構文 val x1 = 1 + 2 val x2 = 1.+(2) implicit class MyInt(val x: Int) extends AnyVal { def add(another: Int): Int = x + another } val y1 = 1.add(2) val y2 = 1 add 2 数値を1つ引数に取るIntのメソッ ド Intに「数値を1つ引数に取るメソッ ド」 であるaddを追加 (※詳細省略) 2018-11-10ゼロから始めるScalaプロジェクト 28 等しい 等しい 「引数を1つ取るメソッド」の呼び出 しは 「.」と「()」を省略できる +α
  • 29. 糖衣構文 class Cat(cry: String) { def apply(postfix: String): Unit = println(cry + postfix) } object Cat { def apply(cry: String): Cat = new Cat(cry) } val cat1 = new Cat("にゃー") val cat2 = Cat("にゃー") val cat3 = Cat.apply("にゃー") cat1("!") cat1.apply("!") 「apply」という名前であればなんでもよ い 2018-11-10ゼロから始めるScalaプロジェクト 29 等しい 「applyという名前のメソッド」の呼び出 しは 「.apply」を省略できる 等しい 配列やリストのインデックス参照が 「()」 でできるのはapplyによるもの +α
  • 30. クラス class Cat(cry: String) val cat = new Cat("にゃー") // cryはprivateなので外部からアクセスできない class Cat(val cry: String) val cat = new Cat("にゃー") // 宣言にvalを付けると外部からアクセスできる println(cat.cry) 2018-11-10ゼロから始めるScalaプロジェクト 30 publicになる デフォルトはprivate varだと更に 再代入可能に +α
  • 31. ケースクラス case class Cat(cry: String) val cat1 = new Cat("にゃー") val cat2 = Cat("にゃー") val cat3 = Cat.apply("にゃー") println(cat1.cry) println(cat1.toString) getData(q) match { case Some(str) => println(str) case None => println("該当なし") } 2018-11-10ゼロから始めるScalaプロジェクト 31 コンストラクタ引数と 等しい引数を持つapplyが 自動的に定義されるため, 見かけ上newが不要になる caseを付けるだけ デフォルトでpublic いい感じのtoString コンストラクタ引数 で パターンマッチ可能 unapply (※詳細省略) 通常のclassに便利機能が自動定義される +α