34
SCALA 始めてみました 6回福岡市西区プログラム勉強会

2013-12-08 西区プログラム勉強会

Embed Size (px)

DESCRIPTION

初心者向けの発表です 発表時間が15分だったのでトレイトなどの話は省略してます

Citation preview

Page 1: 2013-12-08 西区プログラム勉強会

SCALA始めてみました第6回福岡市西区プログラム勉強会

Page 2: 2013-12-08 西区プログラム勉強会

Scala

• この頃何かと話題のScala

• 採用事例 Twitter, Foursquare, LinkedIn

• ウェブ開発 Play framework

• 各地勉強会

• 本発表では

• 基本構文から特徴的機能を紹介して Scalaの魅力を伝える

• 基本情報

• 登場時期 2003年頃

• 設計者 Martin Odersky

• 安定バージョン 2.10.3

• 開発バージョン 2.11.0-M7

2013年 12月 8日 第6回福岡市西区プログラム勉強会 2

Page 3: 2013-12-08 西区プログラム勉強会

Scala

2013年 12月 8日 第6回福岡市西区プログラム勉強会 3

Page 4: 2013-12-08 西区プログラム勉強会

Scalaの特徴

• 純粋なオブジェクト指向言語• クラスベース継承

• traitによるミックスイン合成

• 静的型付け関数型言語• 型推論機構によって簡潔な記述ができる

• 関数型とは 関数も値と同等に扱う

• 定数・変数を扱える

• 簡潔・柔軟な記述が可能

• スケーラブル• 拡張性を持った言語

• 並列コレクション・アクター

• Javaとの互換性• JVM上で動く

• JavaとScalaを相互に利用可能

2013年 12月 8日 第6回福岡市西区プログラム勉強会 4

Page 5: 2013-12-08 西区プログラム勉強会

基本構文

2013年 12月 8日 第6回福岡市西区プログラム勉強会 5

Page 6: 2013-12-08 西区プログラム勉強会

変数

• Byte, Short, Int, Long, Char, String, Float, Double,

Boolean

• すべてオブジェクトとして扱われる

• 変数宣言• val 変数名: 型名 = 初期値 val name: String = “John”

• var 変数名: 型名 = 初期値 var age: Int = 10

• 型推論によって自動的に型が決まる

• val num = 10.0 // => num: Double = 10.0

• 型名を省略することができる

• val と var

• val – 変数の値を変更できない(定数)

• var – 変数の値を変更できる (変数)

2013年 12月 8日 第6回福岡市西区プログラム勉強会 6

Page 7: 2013-12-08 西区プログラム勉強会

制御文

• 条件分岐• if (条件) { // code } else { // code }

• ループ• あまり使わない

• while ・for

2013年 12月 8日 第6回福岡市西区プログラム勉強会 7

val atoz = 'a' to 'z'var i = 0while(i < atoz.length) {

println(atoz(i))i += 1

}

for (num <- 1 until 10)println(num)

Page 8: 2013-12-08 西区プログラム勉強会

制御文

• ループ

2013年 12月 8日 第6回福岡市西区プログラム勉強会 8

atoz.foreach((c: String) => {println(c)

})

atoz.foreach(c => println(c))

args.foreach(println(_))

args.foreach(println)

型推論

プレースホルダー

省略可能

Page 9: 2013-12-08 西区プログラム勉強会

関数

2013年 12月 8日 第6回福岡市西区プログラム勉強会 9

def add(a: Int, b: Int): Int = {a + b

}

関数の宣言 戻り値の型

最後の行が戻り値

関数名

引数

def add(a: Int)(b: Int): Int = a + bval twoAdd = add(2)_println(twoAdd(5))// 7

部分適用

def add(a: Int, b: Int = 10) = a + b

デフォルト引数

Page 10: 2013-12-08 西区プログラム勉強会

クラス

• フィールドとメソッドを持つ

• コンストラクタ• クラス内に記述

• 補助コンストラクタ

• Javaより簡潔に書ける

2013年 12月 8日 第6回福岡市西区プログラム勉強会 10

public class Person {private String name;private int age;

public Person(String name, int age) {this.name = name;this.age = age;

}

public Person(String name) {this(name, 10);

}}

Java

class Person(p: String, n: Int) {val name = pval age = ndef this(p: String) = this(p, 20)

}

Scala

Page 11: 2013-12-08 西区プログラム勉強会

いくつかの機能・構文

2013年 12月 8日 第6回福岡市西区プログラム勉強会 11

Page 12: 2013-12-08 西区プログラム勉強会

例えばこんなコード

2013年 12月 8日 第6回福岡市西区プログラム勉強会 12

package jp.samples

object HelloScala {def main(args: Array[String]): Unit = {

import model.{ Person => CasePerson }val p1 = CasePerson("John", 20)p1.growprintln(p1.hello)println(p1)

}}

package model {case class Person(val name: String, private var age: Int = 20) {

require(name != "")require(age > 0)

def hello(): String = s"Hello, $name"def grow: Int = {

age += 1age

}}

}

Page 13: 2013-12-08 西区プログラム勉強会

例えばこんなコード

2013年 12月 8日 第6回福岡市西区プログラム勉強会 13

package jp.samples

object HelloScala {def main(args: Array[String]): Unit = {

import model.{ Person => CasePerson }val p1 = CasePerson("John", 20)p1.growprintln(p1.hello)println(p1)

}}

package model {case class Person(val name: String, private var age: Int = 20) {

require(name != "")require(age > 0)

def hello(): String = s"Hello, $name"def grow: Int = {

age += 1age

}}

}

Object

import文

require文

加工文字列リテラル

caseクラス

Page 14: 2013-12-08 西区プログラム勉強会

Object

• 単一オブジェクト

• 言語レベルでのシングルトンサポート

• main関数はObjectに書く

2013年 12月 8日 第6回福岡市西区プログラム勉強会 14

object HelloScala {def main(args: Array[String]): Unit = {// code

}}

Page 15: 2013-12-08 西区プログラム勉強会

caseクラス

• newキーワードが不要

• toString, hashCode, equalsの自動実装

2013年 12月 8日 第6回福岡市西区プログラム勉強会 15

case class Person(val name: String, val age: Int)scala> val p1 = Person("John", 20)

p1: Person = Person(John,20)

class Person(val name: String, val age: Int)scala> val p1 = new Person("John", 20)

p1: Person = Person@32076ee4

Page 16: 2013-12-08 西区プログラム勉強会

require文

• インスタンス生成時に引数チェックが可能

• 条件を満たさないと”IllegalArgumentException”を出す

2013年 12月 8日 第6回福岡市西区プログラム勉強会 16

case class Person(val name: String, private var age: Int = 20) {require(name != "")require(age > 0)

}

Page 17: 2013-12-08 西区プログラム勉強会

import文

• 柔軟なインポート

• 指定したパッケージの全クラス

• 指定したクラスのみ

• インポートクラスに別名を与える

• 任意の場所に書ける

• 入れ子構造

2013年 12月 8日 第6回福岡市西区プログラム勉強会 17

import java.math._import java.util.{ List, ArrayList }import model.{ Person => CasePerson }

package jp.samples

package model {case class Person(val name: String, val age: Int) {

require(name != "")require(age > 0)

}}

Page 18: 2013-12-08 西区プログラム勉強会

加工文字リテラル (processed string literal)

• 文字列の前にリテラルをつけることでコンパイラが追加処理をしてくれる

• 補間子

• s 補間子 - 変数を直接扱える

• 例:val value = “fuga”

s”hoge $value” // hoge fuga

• f 補間子 - 書式付き文字列

• 例:f”$name%s $height%2.2f meters” // James is 1.90 meters

• raw 補間子 - エスケープなし

• 例:raw”ab\nc” // ab\nc

• 独自補間子も定義可能

2013年 12月 8日 第6回福岡市西区プログラム勉強会 18

Page 19: 2013-12-08 西区プログラム勉強会

パターンマッチ

2013年 12月 8日 第6回福岡市西区プログラム勉強会 19

Page 20: 2013-12-08 西区プログラム勉強会

パターンマッチ

• 非常に強力なマッチング• 複数の選択肢から一つを選択

• _(アンダースコア)でdefaultの働き

• 値を返す

• 定数マッチ

2013年 12月 8日 第6回福岡市西区プログラム勉強会 20

val str = readLineval msg = str match {

case "hello" => str + " world"case "welcome" => str + " to scala"case _ => "wrong"

}println(msg)

Page 21: 2013-12-08 西区プログラム勉強会

パターンマッチ

• コンストラクターパターン• クラスメンバーまでチェック

2013年 12月 8日 第6回福岡市西区プログラム勉強会 21

object MatchSample {def main(args: Array[String]): Unit = {val p1: Any = Person(“John”, 20)p1 match {

case Person(“John”, _) => println(“He is John”)case Person => println(“Person”)

}}

}case class Person(name: String, age: Int)

Page 22: 2013-12-08 西区プログラム勉強会

パターンマッチ

• 型付きパターン• case 変数名: 型名 => { }

• キャストの代用

2013年 12月 8日 第6回福岡市西区プログラム勉強会 22

object MatchSample {def main(args: Array[String]): Unit = {val p1: Any = Person("John", 20)p1 match {case person: Person => println("Person " + person.name)case animal: Animal => println("Animal is" + animal.aType)

}}

}case class Person(name: String, age: Int)case class Animal(name: String, aType: String)

Page 23: 2013-12-08 西区プログラム勉強会

パターンマッチ

• パターンガード• マッチした後にさらに条件を加える

2013年 12月 8日 第6回福岡市西区プログラム勉強会 23

object MatchSample {def main(args: Array[String]): Unit = {val p1: Any = Person("John", 20)p1 match {case person: Person if person.name == "John" => {println("John " + person.age)

}case person: Person => println("Person " + person.name)case animal: Animal => println("Animal is" + animal.aType)

}}

}case class Person(name: String, age: Int)case class Animal(name: String, aType: String)

Page 24: 2013-12-08 西区プログラム勉強会

リスト操作

2013年 12月 8日 第6回福岡市西区プログラム勉強会 24

Page 25: 2013-12-08 西区プログラム勉強会

リスト操作

• アクセス• head リストの先頭の要素

• tail 先頭以外の要素

• init 最後以外の要素

• last リストの最後の要素

2013年 12月 8日 第6回福岡市西区プログラム勉強会 25

scala> val alpha = ('a' to 'e').toList

alpha: List[Char] = List(a, b, c, d, e)

scala> alpha.head

res1: Char = a

scala> alpha.tail

res2: List[Char] = List(b, c, d, e)

scala> alpha.init

res3: List[Char] = List(a, b, c, d)

scala> alpha.last

res4: Char = e

Page 26: 2013-12-08 西区プログラム勉強会

リスト操作

• 例えば• 名前のリストから頭文字がJの名前を抽出して小文字にして返す

2013年 12月 8日 第6回福岡市西区プログラム勉強会 26

List<String> nameList =Arrays.asList("Alice", "John", "Jack", "Paul");

for (String name : nameList) {List<String> jList = new ArrayList<>();if (name.startsWith("J")) {

jList.add(name.toLowerCase());}

}

Java

val nameList = Array("Alice", "John", "Jack", "Paul")val jList = nameList

.filter(_.startsWith("J"))

.map(_.toLowerCase())

Scala

Page 27: 2013-12-08 西区プログラム勉強会

リスト操作

• filter リストから条件に合う要素を抽出

• map 要素を変換する

2013年 12月 8日 第6回福岡市西区プログラム勉強会 27

scala> (1 to 10).filter(_ > 5).toList

res1: List[Int] = List(6, 7, 8, 9, 10)

scala> (1 to 10).map(_ * 10).toList

res2: List[Int] = List(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

Page 28: 2013-12-08 西区プログラム勉強会

リスト操作

• toListリストに変換する

• toSet Setに変換

• mkString 要素を文字列に

2013年 12月 8日 第6回福岡市西区プログラム勉強会 28

scala> List(1, 1, 2, 3, 5, 5).toSet.toList

res3: List[Int] = List(1, 2, 3, 5)

scala> (1 to 5).mkString("num(", ", ", ")")

res4: String = num(1, 2, 3, 4, 5)

scala> (1 to 5).mkString(", ")

res5: String = 1, 2, 3, 4, 5

Page 29: 2013-12-08 西区プログラム勉強会

リスト操作

• sum 要素の合計

• product 要素の積

• min 最小要素

• max 最大

2013年 12月 8日 第6回福岡市西区プログラム勉強会 29

scala> (1 to 10).sum

res1: Int = 55

scala> (1 to 10).product

res2: Int = 3628800

scala> (1 to 10).max

res4: Int = 10

scala> (1 to 10).min

res3: Int = 1

Page 30: 2013-12-08 西区プログラム勉強会

並列・並行処理

• 並列コレクション• 手軽に並列処理を行える

• 逐次処理 (1 to 100000).sum

• 並列処理 (1 to 100000).par.sum

• Actor

• 各アクターがメッセージパッシングで処理を行う

2013年 12月 8日 第6回福岡市西区プログラム勉強会 30

Page 31: 2013-12-08 西区プログラム勉強会

並列・並行処理

• アクター

2013年 12月 8日 第6回福岡市西区プログラム勉強会 31

object ActorSample {

def main(args: Array[String]): Unit = {

myActor ! 10

}

import scala.actors.Actor

import scala.actors.Actor._

val myActor = actor {

loop {

react {

case i: Int => println("loop react = " + i)

}

}

}

}

Page 32: 2013-12-08 西区プログラム勉強会

もっとScalaを学習したいなら

2013年 12月 8日 第6回福岡市西区プログラム勉強会 32

Scalaスケーラブルプログラミング第2版http://amzn.to/1bOKPBN

Page 33: 2013-12-08 西区プログラム勉強会

もっとScalaを学習したいなら

2013年 12月 8日 第6回福岡市西区プログラム勉強会 33

http://www.scala-lang.org/documentation/

Page 34: 2013-12-08 西区プログラム勉強会

もっとScalaを学習したいなら

2013年 12月 8日 第6回福岡市西区プログラム勉強会 34

http://docs.scala-lang.org/ja/overviews/index.html