SlideShare uma empresa Scribd logo
1 de 36
Baixar para ler offline
1
~ Scala 入門勉強会 ~
山中 瑞起
2013/04/27
2
自己紹介
山中 瑞起(やまなかみずき)
■ Twitter:charlesvineyard
■ facebook:山中 瑞起
■ 現在フリーランスのSE
■ MilmSearchプロジェクトリーダー
 メーリングリスト検索アプリを開発するOSP
 Scalaで開発(1年くらい)
 Playフレームワーク勉強中
僭越ながら本日の講師を
 勤めさせていただきます!
よろしくお願いします!!
3
本日のアジェンダ
■ Scala、関数型言語について
■ 開発環境設定
■ HelloWorld
■ FizzBuzz を題材に Scala を学ぶ
 値を返す if
 値を返す for
 map と高階関数
 map と無名関数
 match-case(パターンマッチ)
 map と match-case
 再帰とクロージャとコンス(分ける方)
 末尾再帰とコンス(連結する方)
4
Scala ってどんな言語?
■ オブジェクト指向言語と関数型言語の
両方の特徴を持っている
 最初は書きやすくなった Java 程度の感覚で
大丈夫
 関数型言語って難しいイメージだけど、Scala
なら段階的に関数型言語っぽく書いていける
 だから勉強しやすくてオトク
5
Scala ってどんな言語?
■ JVM上で動く
 コンパイルすると Java の class ファイル
ができるということ
 Javaの資産がそのまま使える
■ 静的型付け&型推論
 コンパイル時の型チェックで安心安全
 型推論
➔冗長な型の記述が省略可
6
関数型言語って?
■ 関数が値
 Scalaでは関数(メソッド)が1つの型で表せられ
る
 変数に関数を入れることができる
■ 副作用がないプログラム
 副作用とは
➔ある変数の状態が変更され、
処理に影響が出ること
 副作用がないと
➔コードの理解がしやすくバグが入りにくい
➔並列処理がしやい
➔マルチコア対応しやすい
7
Mutable Immutable
■ Mutable(ミュータブル)
 変更できる
 変更するためにある
 状態が変わるので関数型言語的には嫌われる
■ Immutable(イミュータブル)
 変更できない
 関数型言語では好ましい
■ 変更できないのにプログラムは可能なのか?
■ 今日はそこんとこ注目
8
環境設定
■ Eclipse インストール
 公式サイトからダウンロード(種類は
classic)、解凍
 Workspace は差し支えなければデフォルトで
起動
■ Scalaプラグインインストール
 Scala IDE 公式サイト
http://scala-ide.org/
 Eclipse のバージョンに合ったインストール
用URLをクリックしてコピーしておく
 Eclipse の ヘルプ>新規ソフトウェアインス
トール から適宜インストール
9
HelloWorld
■ HelloWorld.scala を作成

新規(new)→Scalaオブジェクト
➔
名前「HelloWorld」
➔
main メソッド定義にチェック
➔
赤字部分だけ記述
■ 実行は「実行」→「実行」
または 緑の三角ボタン
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello World")
}
}
10
HelloWorld.scala 詳細
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello World")
}
}
オブジェクト宣言
● シングルトンオブジェクト
● 他言語で言うところの static メソッドが
定義できるクラス
オブジェクト名
def 関数名
(メソッド名)
関数定義
引数リスト
2つのときは(変数名: 型, 変数名: 型)の形
: に続けて型を書く
戻り値の型
引数と同様 : に続けて型を書く
Unit は戻り値がない時の型(void)。省略可
戻り値ありのときは = を書く
標準出力関数
11
FizzBuzz問題文
■ 1~20までの数を1行ずつ表示する
■ ただし、3で割りきれる数の場合は数の代
わりに「Fizz」と表示する
■ 5で割りきれる数の場合は数の代わりに
「Buzz」と表示する
■ 3でも5でも割りきれる数の場合は
「FizzBuzz」と表示する
12
FizzBuzz01~基本形~
object FizzBuzz01 {
def main(args: Array[String]) {
for (i <- 1 to 20) {
if (i % 3 == 0 && i % 5 ==0) {
println("FuzzBuzz")
} else if (i % 3 == 0) {
println("Fizz")
} else if (i % 5 == 0) {
println("Buzz")
} else {
println(i)
}
}
}
}
 他の言語と同じように、
 if を使って処理を書いてみましょう。
13
FizzBuzz01~基本形~
object FizzBuzz01 {
def main(args: Array[String]) {
for (i <- 1 to 20) {
if (i % 3 == 0 && i % 5 ==0) {
println("FuzzBuzz")
} else if (i % 3 == 0) {
println("Fizz")
} else if (i % 5 == 0) {
println("Buzz")
} else {
println(i)
}
}
}
}
14
FizzBuzz02 ~ifは値を返す~ の前説
// Good if
val valMsg = if (date.getDate % 2 == 0) {
"今日は偶数日です。"
} else {
"今日は奇数日です。"
}
println(valMsg)
// Bad if
var varMsg: String = null
if (date.getDate % 2 == 0) {
varMsg = "今日は偶数日です。"
} else {
varMsg = "今日は奇数日です。"
}
println(varMsg)
15
FizzBuzz02 ~ifは値を返す~
object FizzBuzz01 {
def main(args: Array[String]) {
for (i <- 1 to 20) {
if (i % 3 == 0 && i % 5 ==0) {
println("FuzzBuzz")
} else if (i % 3 == 0) {
println("Fizz")
} else if (i % 5 == 0) {
println("Buzz")
} else {
println(i)
}
}
}
}
object FizzBuzz02 {
def main(args: Array[String]) {
for (i <- 1 to 20) {
val line = if (i % 3 == 0 && i % 5 ==0) {
"FuzzBuzz"
} else if (i % 3 == 0) {
"Fizz"
} else if (i % 5 == 0) {
"Buzz"
} else {
i
}
println(line)
}
}
}
 val、値を返すifを使い、println が1つになるよう
 処理を書いてみましょう。
16
FizzBuzz02 ~ifは値を返す~
object FizzBuzz01 {
def main(args: Array[String]) {
for (i <- 1 to 20) {
if (i % 3 == 0 && i % 5 ==0) {
println("FuzzBuzz")
} else if (i % 3 == 0) {
println("Fizz")
} else if (i % 5 == 0) {
println("Buzz")
} else {
println(i)
}
}
}
}
object FizzBuzz02 {
def main(args: Array[String]) {
for (i <- 1 to 20) {
val line = if (i % 3 == 0 && i % 5 ==0) {
"FuzzBuzz"
} else if (i % 3 == 0) {
"Fizz"
} else if (i % 5 == 0) {
"Buzz"
} else {
i
}
println(line)
}
}
}
17
FizzBuzz03 ~for は yield で値を返す~ の
前説
val lines = for (i <- 1 to 5) yield
if (i == 1)
"壱"
else if (i == 2)
"弐"
else
"参以上"
lines foreach println
// 実行結果
壱
弐
参以上
参以上
参以上
18
FizzBuzz03 ~for は yield で値を返す~
object FizzBuzz03 {
def main(args: Array[String]) {
val lines = for (i <- 1 to 20) yield
if (i % 3 == 0 && i % 5 ==0) {
"FuzzBuzz"
} else if (i % 3 == 0) {
"Fizz"
} else if (i % 5 == 0) {
"Buzz"
} else {
i
}
lines foreach println
}
}
 値を返す for , foreach を使い
 処理を書いてみましょう。
19
FizzBuzz03 ~for は yield で値を返す~
object FizzBuzz03 {
def main(args: Array[String]) {
val lines = for (i <- 1 to 20) yield
if (i % 3 == 0 && i % 5 ==0) {
"FuzzBuzz"
} else if (i % 3 == 0) {
"Fizz"
} else if (i % 5 == 0) {
"Buzz"
} else {
i
}
lines foreach println
}
}
20
FizzBuzz04 ~ map と高階関数~ の前説
// map と高階関数を使った例
def twice(x: Int) = x * 2
(1 to 5) map { x => twice(x) } foreach println
// 省略形
(1 to 5) map { twice(_) } foreach println
(1 to 5) map { twice } foreach println
(1 to 5) map twice foreach println // やりすぎ?
// 実行結果
2
4
6
8
10
21
FizzBuzz04 ~ map と高階関数~
object FizzBuzz04 {
def main(args: Array[String]) {
def fizzbuzz(i: Int): String =
if (i % 3 == 0 && i % 5 == 0)
"FizzBuzz"
else if (i % 3 == 0)
"Fizz"
else if (i % 5 == 0)
"Buzz"
else
i.toString()
1 to 20 map { fizzbuzz } foreach println
}
}
 引数がInt型1つで、String型を返す
 fizzbuzz という名前の関数を定義し、
 map を使って処理を書いてみましょう。
 
22
FizzBuzz04 ~ map と高階関数~
object FizzBuzz04 {
def main(args: Array[String]) {
def fizzbuzz(i: Int): String =
if (i % 3 == 0 && i % 5 == 0)
"FizzBuzz"
else if (i % 3 == 0)
"Fizz"
else if (i % 5 == 0)
"Buzz"
else
i.toString()
1 to 20 map { fizzbuzz } foreach println
}
}
23
FizzBuzz04 ~ map と高階関数~ の後説
// foreach println も同じ形でした
(1 to 5) foreach { x => println(x) }
(1 to 5) foreach { println(_) }
(1 to 5) foreach println
24
FizzBuzz05 ~ map と無名関数~ の前説
(1 to 5) map { (x: Int) => x * 2 } foreach println
// 省略形
(1 to 5) map { x => x * 2 } foreach println
(1 to 5) map { _ * 2 } foreach println
// 実行結果
2
4
6
8
10
25
FizzBuzz05 ~ map と無名関数~
object FizzBuzz05 {
def main(args: Array[String]) {
(1 to 20) map { x =>
if (x % 3 == 0 && x % 5 == 0)
"FizzBuzz"
else if (x % 3 == 0)
"Fizz"
else if (x % 5 == 0)
"Buzz"
else
x.toString
} foreach println
}
}
 map と無名関数を使って
 処理を書いてみましょう。
 
26
FizzBuzz05 ~ map と無名関数~
object FizzBuzz05 {
def main(args: Array[String]) {
(1 to 20) map { x =>
if (x % 3 == 0 && x % 5 == 0)
"FizzBuzz"
else if (x % 3 == 0)
"Fizz"
else if (x % 5 == 0)
"Buzz"
else
x.toString
} foreach println
}
}
27
FizzBuzz06 ~ match-case ~ の前説 1/2
// 例1
val num = 1
val daiji = num match {
case 1 => "壱"
case 2 => "弐"
case _ => "参以上"
}
println(daiji)
// 実行結果
壱
28
FizzBuzz06 ~ match-case ~ の前説 2/2
// 例2
val date = new Date
val msg = date.getDate match {
case d if (d % 2 == 0) => "今日は偶数日です。"
case _ => "今日は奇数日です。"
}
println(msg)
// 実行結果(27日の場合)
今日は奇数日です。
29
FizzBuzz06 ~ match-case ~
object FizzBuzz06 {
def main(args: Array[String]) {
(1 to 20) map { num =>
num match {
case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz"
case x if (x % 3 == 0) => "Fizz"
case x if (x % 5 == 0) => "Buzz"
case x => x.toString()
}
} foreach println
}
}
 match-case を使って
 処理を書いてみましょう。
 
30
FizzBuzz06 ~ match-case ~
object FizzBuzz06 {
def main(args: Array[String]) {
(1 to 20) map { num =>
num match {
case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz"
case x if (x % 3 == 0) => "Fizz"
case x if (x % 5 == 0) => "Buzz"
case x => x.toString()
}
} foreach println
}
}
31
FizzBuzz07 ~ map と match の省略 ~ の前説
val daijis = (1 to 5) map { num =>
num match {
case 1 => "壱"
case 2 => "弐"
case _ => "参以上"
}
}
// 省略形
val daijis2 = (1 to 5) map {
case 1 => "壱"
case 2 => "弐"
case _ => "参以上"
}
32
FizzBuzz07 ~ map と match の省略 ~
object FizzBuzz07 {
def main(args: Array[String]) {
1 to 20 map {
case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz"
case x if (x % 3 == 0) => "Fizz"
case x if (x % 5 == 0) => "Buzz"
case x => x.toString()
} foreach println
}
}
 match を省略した
 処理を書いてみましょう。
 
33
FizzBuzz07 ~ map と match の省略 ~
object FizzBuzz07 {
def main(args: Array[String]) {
1 to 20 map {
case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz"
case x if (x % 3 == 0) => "Fizz"
case x if (x % 5 == 0) => "Buzz"
case x => x.toString()
} foreach println
}
}
34
FizzBuzz08 ~ 再帰、クロージャ、コンス(分ける) ~
import scala.collection.mutable.ListBuffer
object FizzBuzz08 {
def main(args: Array[String]) {
val lines = new ListBuffer[String]
def fizzbuzzRec(numbers: List[Int]) {
numbers match {
case Nil =>
case number :: tail => {
lines.append(number match {
case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz"
case x if (x % 3 == 0) => "Fizz"
case x if (x % 5 == 0) => "Buzz"
case x => x.toString
})
fizzbuzzRec(tail)
}
}
}
fizzbuzzRec(1 to 20 toList)
lines foreach println
}
}
35
FizzBuzz09 ~ 末尾再帰、コンス(連結) ~
import scala.collection.mutable.ListBuffer
import scala.annotation.tailrec
object FizzBuzz09 {
def main(args: Array[String]) {
def fizzbuzzRec(numbers: List[Int]): List[String] = {
@tailrec
def fizzbuzzRecLocal(accumulator: List[String],
numbers: List[Int]): List[String] = {
numbers match {
case Nil => accumulator
case number :: tail => fizzbuzzRecLocal(
accumulator ::: List(
number match {
case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz"
case x if (x % 3 == 0) => "Fizz"
case x if (x % 5 == 0) => "Buzz"
case x => x.toString
}
), tail
)
}
}
fizzbuzzRecLocal(Nil, numbers)
}
fizzbuzzRec(1 to 20 toList) foreach println
}
}
36
おすすめ書籍
■ オブジェクト指向プログラマが次に読む本
-Scalaで学ぶ関数脳入門
株式会社テクノロジックアート、
長瀬 嘉秀、 町田 修一
■ Scalaスケーラブルプログラミング第2版
Martin Odersky、Lex Spoon、Bill Venners、
羽生田 栄一
■ Scala実践プログラミング
―オープンソース徹底活用
小笠原 啓、尾崎 智仁、関 隆、 水島 宏太
■ Scalaプログラミング入門
デイビッド・ポラック、羽生田栄一、 大塚庸史

Mais conteúdo relacionado

Mais procurados

x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTtakesako
 
RでGISハンズオンセッション
RでGISハンズオンセッションRでGISハンズオンセッション
RでGISハンズオンセッションarctic_tern265
 
Goをカンストさせる話
Goをカンストさせる話Goをカンストさせる話
Goをカンストさせる話Moriyoshi Koizumi
 
KMC JavaScriptから始めるプログラミング2016 第一回
KMC JavaScriptから始めるプログラミング2016 第一回KMC JavaScriptから始めるプログラミング2016 第一回
KMC JavaScriptから始めるプログラミング2016 第一回kyoto university
 
brainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusablebrainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusableroodni
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編egtra
 
何もないところから数を作る
何もないところから数を作る何もないところから数を作る
何もないところから数を作るTaketo Sano
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCamlHaruka Oikawa
 
ベクトル空間と表現行列
ベクトル空間と表現行列ベクトル空間と表現行列
ベクトル空間と表現行列政孝 鍋島
 
ベクトル空間と表現行列
ベクトル空間と表現行列ベクトル空間と表現行列
ベクトル空間と表現行列nabeshimamasataka
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたblackenedgold
 
何もないところから数を作る
何もないところから数を作る何もないところから数を作る
何もないところから数を作るTaketo Sano
 

Mais procurados (20)

x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNT
 
CG2013 05
CG2013 05CG2013 05
CG2013 05
 
RでGISハンズオンセッション
RでGISハンズオンセッションRでGISハンズオンセッション
RでGISハンズオンセッション
 
Goをカンストさせる話
Goをカンストさせる話Goをカンストさせる話
Goをカンストさせる話
 
KMC JavaScriptから始めるプログラミング2016 第一回
KMC JavaScriptから始めるプログラミング2016 第一回KMC JavaScriptから始めるプログラミング2016 第一回
KMC JavaScriptから始めるプログラミング2016 第一回
 
brainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusablebrainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusable
 
実用Brainf*ckプログラミング
実用Brainf*ckプログラミング実用Brainf*ckプログラミング
実用Brainf*ckプログラミング
 
RでGIS
RでGISRでGIS
RでGIS
 
CG2013 03
CG2013 03CG2013 03
CG2013 03
 
初めてのSTL
初めてのSTL初めてのSTL
初めてのSTL
 
機械学習
機械学習機械学習
機械学習
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
 
Gnuplotあれこれ
GnuplotあれこれGnuplotあれこれ
Gnuplotあれこれ
 
何もないところから数を作る
何もないところから数を作る何もないところから数を作る
何もないところから数を作る
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
python-geohex
python-geohexpython-geohex
python-geohex
 
ベクトル空間と表現行列
ベクトル空間と表現行列ベクトル空間と表現行列
ベクトル空間と表現行列
 
ベクトル空間と表現行列
ベクトル空間と表現行列ベクトル空間と表現行列
ベクトル空間と表現行列
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみた
 
何もないところから数を作る
何もないところから数を作る何もないところから数を作る
何もないところから数を作る
 

Destaque

Mizukiryu refactering-20110821
Mizukiryu refactering-20110821Mizukiryu refactering-20110821
Mizukiryu refactering-20110821Mizuki Yamanaka
 
バージョン管理の断捨離
バージョン管理の断捨離バージョン管理の断捨離
バージョン管理の断捨離Kazushi Kamegawa
 
【勉強会】パターンによるソフトウェア構成管理
【勉強会】パターンによるソフトウェア構成管理【勉強会】パターンによるソフトウェア構成管理
【勉強会】パターンによるソフトウェア構成管理zuisener .
 
構成管理のアンチパターン
構成管理のアンチパターン構成管理のアンチパターン
構成管理のアンチパターンakipii Oga
 
Jenkinsを利用したCI、弊社導入事例
Jenkinsを利用したCI、弊社導入事例Jenkinsを利用したCI、弊社導入事例
Jenkinsを利用したCI、弊社導入事例Ryoichi Obara
 
Startup jenkins!
Startup jenkins!Startup jenkins!
Startup jenkins!Kanu orz
 

Destaque (7)

Mizukiryu refactering-20110821
Mizukiryu refactering-20110821Mizukiryu refactering-20110821
Mizukiryu refactering-20110821
 
バージョン管理の断捨離
バージョン管理の断捨離バージョン管理の断捨離
バージョン管理の断捨離
 
【勉強会】パターンによるソフトウェア構成管理
【勉強会】パターンによるソフトウェア構成管理【勉強会】パターンによるソフトウェア構成管理
【勉強会】パターンによるソフトウェア構成管理
 
構成管理のアンチパターン
構成管理のアンチパターン構成管理のアンチパターン
構成管理のアンチパターン
 
Jenkinsを利用したCI、弊社導入事例
Jenkinsを利用したCI、弊社導入事例Jenkinsを利用したCI、弊社導入事例
Jenkinsを利用したCI、弊社導入事例
 
Jenkinsのある生活
Jenkinsのある生活Jenkinsのある生活
Jenkinsのある生活
 
Startup jenkins!
Startup jenkins!Startup jenkins!
Startup jenkins!
 

wakuwaku Scala ~Scala入門勉強会~ 資料

  • 1. 1 ~ Scala 入門勉強会 ~ 山中 瑞起 2013/04/27
  • 2. 2 自己紹介 山中 瑞起(やまなかみずき) ■ Twitter:charlesvineyard ■ facebook:山中 瑞起 ■ 現在フリーランスのSE ■ MilmSearchプロジェクトリーダー  メーリングリスト検索アプリを開発するOSP  Scalaで開発(1年くらい)  Playフレームワーク勉強中 僭越ながら本日の講師を  勤めさせていただきます! よろしくお願いします!!
  • 3. 3 本日のアジェンダ ■ Scala、関数型言語について ■ 開発環境設定 ■ HelloWorld ■ FizzBuzz を題材に Scala を学ぶ  値を返す if  値を返す for  map と高階関数  map と無名関数  match-case(パターンマッチ)  map と match-case  再帰とクロージャとコンス(分ける方)  末尾再帰とコンス(連結する方)
  • 4. 4 Scala ってどんな言語? ■ オブジェクト指向言語と関数型言語の 両方の特徴を持っている  最初は書きやすくなった Java 程度の感覚で 大丈夫  関数型言語って難しいイメージだけど、Scala なら段階的に関数型言語っぽく書いていける  だから勉強しやすくてオトク
  • 5. 5 Scala ってどんな言語? ■ JVM上で動く  コンパイルすると Java の class ファイル ができるということ  Javaの資産がそのまま使える ■ 静的型付け&型推論  コンパイル時の型チェックで安心安全  型推論 ➔冗長な型の記述が省略可
  • 6. 6 関数型言語って? ■ 関数が値  Scalaでは関数(メソッド)が1つの型で表せられ る  変数に関数を入れることができる ■ 副作用がないプログラム  副作用とは ➔ある変数の状態が変更され、 処理に影響が出ること  副作用がないと ➔コードの理解がしやすくバグが入りにくい ➔並列処理がしやい ➔マルチコア対応しやすい
  • 7. 7 Mutable Immutable ■ Mutable(ミュータブル)  変更できる  変更するためにある  状態が変わるので関数型言語的には嫌われる ■ Immutable(イミュータブル)  変更できない  関数型言語では好ましい ■ 変更できないのにプログラムは可能なのか? ■ 今日はそこんとこ注目
  • 8. 8 環境設定 ■ Eclipse インストール  公式サイトからダウンロード(種類は classic)、解凍  Workspace は差し支えなければデフォルトで 起動 ■ Scalaプラグインインストール  Scala IDE 公式サイト http://scala-ide.org/  Eclipse のバージョンに合ったインストール 用URLをクリックしてコピーしておく  Eclipse の ヘルプ>新規ソフトウェアインス トール から適宜インストール
  • 9. 9 HelloWorld ■ HelloWorld.scala を作成  新規(new)→Scalaオブジェクト ➔ 名前「HelloWorld」 ➔ main メソッド定義にチェック ➔ 赤字部分だけ記述 ■ 実行は「実行」→「実行」 または 緑の三角ボタン object HelloWorld { def main(args: Array[String]): Unit = { println("Hello World") } }
  • 10. 10 HelloWorld.scala 詳細 object HelloWorld { def main(args: Array[String]): Unit = { println("Hello World") } } オブジェクト宣言 ● シングルトンオブジェクト ● 他言語で言うところの static メソッドが 定義できるクラス オブジェクト名 def 関数名 (メソッド名) 関数定義 引数リスト 2つのときは(変数名: 型, 変数名: 型)の形 : に続けて型を書く 戻り値の型 引数と同様 : に続けて型を書く Unit は戻り値がない時の型(void)。省略可 戻り値ありのときは = を書く 標準出力関数
  • 11. 11 FizzBuzz問題文 ■ 1~20までの数を1行ずつ表示する ■ ただし、3で割りきれる数の場合は数の代 わりに「Fizz」と表示する ■ 5で割りきれる数の場合は数の代わりに 「Buzz」と表示する ■ 3でも5でも割りきれる数の場合は 「FizzBuzz」と表示する
  • 12. 12 FizzBuzz01~基本形~ object FizzBuzz01 { def main(args: Array[String]) { for (i <- 1 to 20) { if (i % 3 == 0 && i % 5 ==0) { println("FuzzBuzz") } else if (i % 3 == 0) { println("Fizz") } else if (i % 5 == 0) { println("Buzz") } else { println(i) } } } }  他の言語と同じように、  if を使って処理を書いてみましょう。
  • 13. 13 FizzBuzz01~基本形~ object FizzBuzz01 { def main(args: Array[String]) { for (i <- 1 to 20) { if (i % 3 == 0 && i % 5 ==0) { println("FuzzBuzz") } else if (i % 3 == 0) { println("Fizz") } else if (i % 5 == 0) { println("Buzz") } else { println(i) } } } }
  • 14. 14 FizzBuzz02 ~ifは値を返す~ の前説 // Good if val valMsg = if (date.getDate % 2 == 0) { "今日は偶数日です。" } else { "今日は奇数日です。" } println(valMsg) // Bad if var varMsg: String = null if (date.getDate % 2 == 0) { varMsg = "今日は偶数日です。" } else { varMsg = "今日は奇数日です。" } println(varMsg)
  • 15. 15 FizzBuzz02 ~ifは値を返す~ object FizzBuzz01 { def main(args: Array[String]) { for (i <- 1 to 20) { if (i % 3 == 0 && i % 5 ==0) { println("FuzzBuzz") } else if (i % 3 == 0) { println("Fizz") } else if (i % 5 == 0) { println("Buzz") } else { println(i) } } } } object FizzBuzz02 { def main(args: Array[String]) { for (i <- 1 to 20) { val line = if (i % 3 == 0 && i % 5 ==0) { "FuzzBuzz" } else if (i % 3 == 0) { "Fizz" } else if (i % 5 == 0) { "Buzz" } else { i } println(line) } } }  val、値を返すifを使い、println が1つになるよう  処理を書いてみましょう。
  • 16. 16 FizzBuzz02 ~ifは値を返す~ object FizzBuzz01 { def main(args: Array[String]) { for (i <- 1 to 20) { if (i % 3 == 0 && i % 5 ==0) { println("FuzzBuzz") } else if (i % 3 == 0) { println("Fizz") } else if (i % 5 == 0) { println("Buzz") } else { println(i) } } } } object FizzBuzz02 { def main(args: Array[String]) { for (i <- 1 to 20) { val line = if (i % 3 == 0 && i % 5 ==0) { "FuzzBuzz" } else if (i % 3 == 0) { "Fizz" } else if (i % 5 == 0) { "Buzz" } else { i } println(line) } } }
  • 17. 17 FizzBuzz03 ~for は yield で値を返す~ の 前説 val lines = for (i <- 1 to 5) yield if (i == 1) "壱" else if (i == 2) "弐" else "参以上" lines foreach println // 実行結果 壱 弐 参以上 参以上 参以上
  • 18. 18 FizzBuzz03 ~for は yield で値を返す~ object FizzBuzz03 { def main(args: Array[String]) { val lines = for (i <- 1 to 20) yield if (i % 3 == 0 && i % 5 ==0) { "FuzzBuzz" } else if (i % 3 == 0) { "Fizz" } else if (i % 5 == 0) { "Buzz" } else { i } lines foreach println } }  値を返す for , foreach を使い  処理を書いてみましょう。
  • 19. 19 FizzBuzz03 ~for は yield で値を返す~ object FizzBuzz03 { def main(args: Array[String]) { val lines = for (i <- 1 to 20) yield if (i % 3 == 0 && i % 5 ==0) { "FuzzBuzz" } else if (i % 3 == 0) { "Fizz" } else if (i % 5 == 0) { "Buzz" } else { i } lines foreach println } }
  • 20. 20 FizzBuzz04 ~ map と高階関数~ の前説 // map と高階関数を使った例 def twice(x: Int) = x * 2 (1 to 5) map { x => twice(x) } foreach println // 省略形 (1 to 5) map { twice(_) } foreach println (1 to 5) map { twice } foreach println (1 to 5) map twice foreach println // やりすぎ? // 実行結果 2 4 6 8 10
  • 21. 21 FizzBuzz04 ~ map と高階関数~ object FizzBuzz04 { def main(args: Array[String]) { def fizzbuzz(i: Int): String = if (i % 3 == 0 && i % 5 == 0) "FizzBuzz" else if (i % 3 == 0) "Fizz" else if (i % 5 == 0) "Buzz" else i.toString() 1 to 20 map { fizzbuzz } foreach println } }  引数がInt型1つで、String型を返す  fizzbuzz という名前の関数を定義し、  map を使って処理を書いてみましょう。  
  • 22. 22 FizzBuzz04 ~ map と高階関数~ object FizzBuzz04 { def main(args: Array[String]) { def fizzbuzz(i: Int): String = if (i % 3 == 0 && i % 5 == 0) "FizzBuzz" else if (i % 3 == 0) "Fizz" else if (i % 5 == 0) "Buzz" else i.toString() 1 to 20 map { fizzbuzz } foreach println } }
  • 23. 23 FizzBuzz04 ~ map と高階関数~ の後説 // foreach println も同じ形でした (1 to 5) foreach { x => println(x) } (1 to 5) foreach { println(_) } (1 to 5) foreach println
  • 24. 24 FizzBuzz05 ~ map と無名関数~ の前説 (1 to 5) map { (x: Int) => x * 2 } foreach println // 省略形 (1 to 5) map { x => x * 2 } foreach println (1 to 5) map { _ * 2 } foreach println // 実行結果 2 4 6 8 10
  • 25. 25 FizzBuzz05 ~ map と無名関数~ object FizzBuzz05 { def main(args: Array[String]) { (1 to 20) map { x => if (x % 3 == 0 && x % 5 == 0) "FizzBuzz" else if (x % 3 == 0) "Fizz" else if (x % 5 == 0) "Buzz" else x.toString } foreach println } }  map と無名関数を使って  処理を書いてみましょう。  
  • 26. 26 FizzBuzz05 ~ map と無名関数~ object FizzBuzz05 { def main(args: Array[String]) { (1 to 20) map { x => if (x % 3 == 0 && x % 5 == 0) "FizzBuzz" else if (x % 3 == 0) "Fizz" else if (x % 5 == 0) "Buzz" else x.toString } foreach println } }
  • 27. 27 FizzBuzz06 ~ match-case ~ の前説 1/2 // 例1 val num = 1 val daiji = num match { case 1 => "壱" case 2 => "弐" case _ => "参以上" } println(daiji) // 実行結果 壱
  • 28. 28 FizzBuzz06 ~ match-case ~ の前説 2/2 // 例2 val date = new Date val msg = date.getDate match { case d if (d % 2 == 0) => "今日は偶数日です。" case _ => "今日は奇数日です。" } println(msg) // 実行結果(27日の場合) 今日は奇数日です。
  • 29. 29 FizzBuzz06 ~ match-case ~ object FizzBuzz06 { def main(args: Array[String]) { (1 to 20) map { num => num match { case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz" case x if (x % 3 == 0) => "Fizz" case x if (x % 5 == 0) => "Buzz" case x => x.toString() } } foreach println } }  match-case を使って  処理を書いてみましょう。  
  • 30. 30 FizzBuzz06 ~ match-case ~ object FizzBuzz06 { def main(args: Array[String]) { (1 to 20) map { num => num match { case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz" case x if (x % 3 == 0) => "Fizz" case x if (x % 5 == 0) => "Buzz" case x => x.toString() } } foreach println } }
  • 31. 31 FizzBuzz07 ~ map と match の省略 ~ の前説 val daijis = (1 to 5) map { num => num match { case 1 => "壱" case 2 => "弐" case _ => "参以上" } } // 省略形 val daijis2 = (1 to 5) map { case 1 => "壱" case 2 => "弐" case _ => "参以上" }
  • 32. 32 FizzBuzz07 ~ map と match の省略 ~ object FizzBuzz07 { def main(args: Array[String]) { 1 to 20 map { case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz" case x if (x % 3 == 0) => "Fizz" case x if (x % 5 == 0) => "Buzz" case x => x.toString() } foreach println } }  match を省略した  処理を書いてみましょう。  
  • 33. 33 FizzBuzz07 ~ map と match の省略 ~ object FizzBuzz07 { def main(args: Array[String]) { 1 to 20 map { case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz" case x if (x % 3 == 0) => "Fizz" case x if (x % 5 == 0) => "Buzz" case x => x.toString() } foreach println } }
  • 34. 34 FizzBuzz08 ~ 再帰、クロージャ、コンス(分ける) ~ import scala.collection.mutable.ListBuffer object FizzBuzz08 { def main(args: Array[String]) { val lines = new ListBuffer[String] def fizzbuzzRec(numbers: List[Int]) { numbers match { case Nil => case number :: tail => { lines.append(number match { case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz" case x if (x % 3 == 0) => "Fizz" case x if (x % 5 == 0) => "Buzz" case x => x.toString }) fizzbuzzRec(tail) } } } fizzbuzzRec(1 to 20 toList) lines foreach println } }
  • 35. 35 FizzBuzz09 ~ 末尾再帰、コンス(連結) ~ import scala.collection.mutable.ListBuffer import scala.annotation.tailrec object FizzBuzz09 { def main(args: Array[String]) { def fizzbuzzRec(numbers: List[Int]): List[String] = { @tailrec def fizzbuzzRecLocal(accumulator: List[String], numbers: List[Int]): List[String] = { numbers match { case Nil => accumulator case number :: tail => fizzbuzzRecLocal( accumulator ::: List( number match { case x if (x % 3 == 0 && x % 5 == 0) => "FizzBuzz" case x if (x % 3 == 0) => "Fizz" case x if (x % 5 == 0) => "Buzz" case x => x.toString } ), tail ) } } fizzbuzzRecLocal(Nil, numbers) } fizzbuzzRec(1 to 20 toList) foreach println } }
  • 36. 36 おすすめ書籍 ■ オブジェクト指向プログラマが次に読む本 -Scalaで学ぶ関数脳入門 株式会社テクノロジックアート、 長瀬 嘉秀、 町田 修一 ■ Scalaスケーラブルプログラミング第2版 Martin Odersky、Lex Spoon、Bill Venners、 羽生田 栄一 ■ Scala実践プログラミング ―オープンソース徹底活用 小笠原 啓、尾崎 智仁、関 隆、 水島 宏太 ■ Scalaプログラミング入門 デイビッド・ポラック、羽生田栄一、 大塚庸史

Notas do Editor

  1. 次ページのサンプルプログラムで、次の項目をマスターします クラス宣言とオブジェクト宣言 変数宣言 変更できる変数 変更できない変数 メソッド宣言 省略記法 Sample1.scala ファイルで説明した後、 Sample2.scala で省略記法バージョンを書いてみます
  2. class Person { def getMessage(): String = { return &quot;Hello world!&quot; } def printMessage(): Unit = { println(&quot;wakuwaku Scala!&quot;) } } object Main { def main(args: Array[String]): Unit = { val person1 = new Person() println(person1.getMessage()) var person2 = new Person() person2.printMessage() person2 = new Person() person2.printMessage() } } class Person2 { def getMessage = &quot;Hello world!&quot; def printMessage { println(&quot;wakuwaku Scala!&quot;) } } object Main2 { def main(args: Array[String]) { val person1 = new Person println(person1.getMessage) var person2 = new Person person2.printMessage person2 = new Person person2.printMessage } }