$ scala
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server
VM, Java 1.6.0_37).
Type in expressions to have them evaluated.
Type :help for more information.
scala> 1 + 2
res0: Int = 3
scala> println("1 + 2 = " + res0)
1 + 2 = 3
scala> :quit
Slide 12
Slide 12 text
case Ϋϥε
case Ϋϥε
Slide 13
Slide 13 text
ͬͦ͘͞Ͱ͕͢…
case Ϋϥε
Slide 14
Slide 14 text
Java Ͱ
σʔλΫϥεΛ
࣮͢Δͷͬͯ
໘͡Όͳ͍Ͱ͔͢ʁ
case Ϋϥε
Slide 15
Slide 15 text
public class Person {
private String name = null;
private int age = 0;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
Java
Person
- name: String
- age: int
case Ϋϥε
Slide 16
Slide 16 text
Կ͕͔ʁ
• େྔͷ”ϘΠϥʔϓϨʔτ”ͳίʔυ
• ৽͍͠ΫϥεΛ࣮͢ΔͨΊͷίετ͕ߴ͍ɻ
• ”࣮ͷҙਤ”͕ຊ࣭తͰͳ͍෦ʹຒΕͯ͠·͏ɻ
Person
- name: String
- age: int
case Ϋϥε
ɾɾɾ
Slide 17
Slide 17 text
Scala Ͱ
ॻ͍ͯΈΔͱ…ʁ
case Ϋϥε
Slide 18
Slide 18 text
class Person(var name: String, var age: Int)
Person
- name: String
- age: int
Scala
ͨͬͨҰߦʂ
ˍ
Ϋϥεͷҙਤ͕໌֬ʂ
var/val Λ͚ͭΔ
case Ϋϥε
Slide 19
Slide 19 text
class Person(var name: String, var age: Int)
Scala
class Person(name: String, age: Int) {
def name: String = name
def name_=(name: String) { this.name = name }
def age: Int = age
def age_=(age: Int) { this.age = age }
}
getter
setter
ίϯετϥΫλ
ʹ
ΞΫηα͕ࣗಈతʹఆٛ͞ΕΔ
ʢຊͷ Scala ίʔυͰͳ͍͚Ͳɺงғؾ͜Μͳײ͡ͱ͍͏͜ͱͰʣ
case Ϋϥε
Slide 20
Slide 20 text
val p = new Person(“Tom Green”, 25)
println(“age: ” + p.age) // p.age()
p.name = “Martin Odersky” // p.name_=(“Martin Odersky”)
Scala
ϑΟʔϧυͱಉ͡จ๏Ͱ
ࢀরɾߋ৽Ͱ͖Δ
ʢ࣮ࡍͷॲཧ getter/setter Λܦ༝͢ΔͷͰ
ΧϓηϧԽ͕कΒΕΔʣ
case Ϋϥε
Slide 21
Slide 21 text
ͦ͏͍͑…
case Ϋϥε
Slide 22
Slide 22 text
toString ͱ͔
equals ͱ͔
hashCode ͷ࣮
໘͡Όͳ͍Ͱ͔͢ʁ
case Ϋϥε
Slide 23
Slide 23 text
public class Person {
private String name = null;
private int age = 0;
...
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj instanceof Person) {
Person rhs = (Person) obj;
if (this.name == null) return rhs.name == null;
return this.name.equals(rhs.name) && this.age == rhs.age;
}
return super.equals(obj);
}
public int hashCode() {
return 31 * this.name.hashCode() + this.age;
}
public String toString() {
return “Person(” + this.name + “,” + this.age + “)”;
}
}
Java
case Ϋϥε
ਖ਼࣮͘͢͠Δͷେม…
Slide 24
Slide 24 text
ͦ͜Ͱ case Ϋϥε
case Ϋϥε
Slide 25
Slide 25 text
case class Person(var name: String, var age: Int)
Scala
એݴʹ case ͱॻ͚ͩ͘ʂ
case Ϋϥε
Slide 26
Slide 26 text
case class Person(var name: String, var age: Int)
val p1 = Person(“Tom Green”, 25)
val p2 = Person(“Martin Odersky”, 54)
p1.equals(p2)
hashSet.add(p1) // depends on hashCode()
println(p1.toString()) // “Person(Tom Green,25)”
Scala
શͯࣗಈతʹ࣮͞ΕΔ
case Ϋϥε
Slide 27
Slide 27 text
Scala Λ͏ͱ
”ܕ”Λ؆୯ʹ
ఆٛͰ͖Δ
case Ϋϥε
Slide 28
Slide 28 text
case Ϋϥε
from https://github.com/twitter/finagle/
ྫ: memcached ͷϓϩτίϧఆٛ
େྔͷܕఆ͕ٛඞཁ
Slide 29
Slide 29 text
case Ϋϥε
from https://github.com/twitter/finagle/
ྫ: memcached ͷϓϩτίϧఆٛ
େྔͷܕఆ͕ٛඞཁ
ΫϥεΛ؆͔ܿͭݟ௨͠ྑ͘هड़Ͱ͖Δ
㱺 ”ܕͷྗ”Λ؆୯ʹҾ͖ग़ͤΔʂ
Slide 30
Slide 30 text
·ͱΊ
• Scala ʹσʔλΫϥε༻ͷҥߏจ͕͋Δɻ
• ίϯετϥΫλ getter/setter Λࣗಈతʹఆٛ͢Δ
ҥߏจɻ
• equals() Λࣗಈతʹ࣮͢Δ case Ϋϥεɻ
• case Ϋϥεͷ͝རӹଞʹɻৄ͘͠ޙ΄Ͳ…
case Ϋϥε
ch match {
case ‘ ‘ =>
buf.append(‘-’)
case ‘¥n’ =>
buf.append(‘:’)
case _ =>
buf.append(ch)
}
Scala
switch (ch) {
case ‘ ’:
buf.append(‘-’);
break;
case ‘¥n’:
buf.append(‘:’);
break;
default:
buf.append(ch);
break;
}
Java
ߏจࣅ͍ͯΔ
•switch ͷΘΓʹ match Λ͏ɻ
•۠Γه߸ => Λ͏ɻ
•ϑΥʔϧεϧʔ͠ͳ͍ɻ
break จෆཁ
ύλʔϯϚον
Slide 36
Slide 36 text
match ࣜͰ͔͠
Ͱ͖ͳ͍͜ͱ
ύλʔϯϚον
Slide 37
Slide 37 text
abstract class Tree
case object Empty extends Tree
case class Node(
elem: Int, left: Tree, right: Tree)
extends Tree
Tree
Empty
- elem: Int
- left: Tree
- right: Tree
ྫ: ೋ
Node
ύλʔϯϚον
Slide 38
Slide 38 text
abstract class Tree
case object Empty extends Tree
case class Node(
elem: Int, left: Tree, right: Tree) extends Tree
def traverse(t: Tree) = t match {
case empty: Empty => Nil
case node: Node => traverse(node.left) :::
List(node.elem) ::: traverse(node.right)
}
Scala
ύλʔϯϚον
ͷܕΛൺֱͰ͖Δ
Node ͔ΒதͷΛऔΓग़͢ࡍʹɺ
Tree ͔Β Node ͷΩϟετ͕ෆཁͳ͜ͱʹʂ
Slide 39
Slide 39 text
abstract class Tree
case object Empty extends Tree
case class Node(elem: Int, left: Tree, right: Tree)
extends Tree
def traverse(t: Tree) = t match {
case Empty => Nil
case Node(e, l, r) =>
traverse(l) ::: List(e) ::: traverse(r)
}
Scala
ύλʔϯϚον
தΛநग़Ͱ͖Δʂ
ͷநग़ case Ϋϥεͷػೳͷͻͱͭ
ίϯετϥΫλͱಉ͡ه๏ʂ
Slide 40
Slide 40 text
ೖΕࢠʹͳ͍ͬͯͯ
ղͰ͖Δ
t match {
case Node(e1,
Node(e2, Empty, Empty),
Node(e3, Empty, Empty)) => ...
case ...
}
Scala
ύλʔϯϚον
e1
e2
E
e3
E E
E
Slide 41
Slide 41 text
case class Person(name: String, age: Int)
def isAdult(p: Person) = p match {
case Person(“Martin Odersky”, _) => true
case Person(_, age) if (age >= 18) => true
case _ => false
}
Scala
ύλʔϯϚον
ෳࡶͳ݅ذ
؆ܿʹهड़Ͱ͖Δ
໊લ͕ Ұக ͨ͠Β true
18 ࡀ Ҏ্ ͳΒ true
_ ϫΠϧυΧʔυ
Slide 42
Slide 42 text
GoF ͷ
Visitor ύλʔϯ
ύλʔϯϚον
Slide 43
Slide 43 text
Visitor ύλʔϯ…ΞϧΰϦζϜΛΦϒδΣΫτͷߏ
͔Β͢ΔͨΊͷσβΠϯύλʔϯͰ͋Δɻ
ʹΑΔ࣮༻తͳ݁Ռͱͯ͠ɺطଘͷΦϒδΣΫτʹର
͢Δ৽ͨͳૢ࡞ΛߏΛมߋͤͣʹՃ͢Δ͜ͱ͕Ͱ
͖Δɻ
from http://ja.wikipedia.org/wiki/Visitor_ύλʔϯ
ύλʔϯϚον
Slide 44
Slide 44 text
class CarElementPrintVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println("Visiting " + wheel.getName() + " wheel");
}
public void visit(Engine engine) {
System.out.println("Visiting engine");
}
public void visit(Body body) {
System.out.println("Visiting body");
}
public void visit(Car car) {
System.out.println("Visiting car");
}
}
class CarElementDoVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println(
"Kicking my " + wheel.getName() + " wheel");
}
public void visit(Engine engine) {
System.out.println("Starting my engine");
}
public void visit(Body body) {
System.out.println("Moving my body");
}
public void visit(Car car) {
System.out.println("Starting my car");
}
}
ύλʔϯϚον
from http://en.wikipedia.org/wiki/Visitor_pattern
ͳʹ͜Ε͜Θ͍ (ʀʉʔʉ)
interface CarElementVisitor {
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visit(Car car);
}
interface CarElement {
void accept(CarElementVisitor visitor);
}
class Wheel implements CarElement {
private String name;
public Wheel(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Engine implements CarElement {
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Body implements CarElement {
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Car implements CarElement {
CarElement[] elements;
public Car() { ... }
public void accept(CarElementVisitor visitor) {
for(CarElement elem : elements) {
elem.accept(visitor);
}
visitor.visit(this);
}
}
Java
Slide 45
Slide 45 text
ύλʔϯϚονͳΒ
Visitor ύλʔϯ
ෆཁʂ
ύλʔϯϚον
Slide 46
Slide 46 text
abstract class CarElement
case class Wheel(name: String) extends CarElement
case object Engine extends CarElement
case object Body extends CarElement
case class Car(elements: List[CarElement]) extends CarElement
def print(elem: CarElement) = elem match {
case Wheel(name) => println(“Visiting” + name + “ wheel”)
case Engine => println(“Visiting engine”)
case Body => println(“Visiting body”)
case Car(elements) =>
elements foreach print; println(“Visiting car”)
}
def doSomething(elem: CarElement) = elem match {
case Wheel(name) => println(“Kicking my ” + name + “ wheel”)
case Engine => println(“Starting my engine”)
case Body => println(“Moving my body”)
case Car(elements) =>
elements foreach doSomething; println(“Starting my car”)
}
Scala
ύλʔϯϚον
I call it my billion-dollar mistake. It was the
invention of the null reference in 1965.
Tony Hoare (2009). “Null Reference: The Billion Dollar Mistake”. QCon London
“null 10 ԯυϧͷࣦഊ”
※ʮΫΠοΫιʔτʯΛൃ໌ͨ͠ਓ
Option ܕ
Slide 79
Slide 79 text
͋Γ͕ͪͳόά
Person person = map.get(“tom”);
println(person.getName());
Option ܕ
map.get
null Λฦ͔͢…
NullPointerException!
sealed abstract class Option[+A]
final case class Some[+A](x: A) extends Option[A]
object None extends Option[Nothing]
Option
None
-x: A
Some
ͦ͜Ͱ Option ܕ
Option ܕ
”ࣦഊͨ͠ܭࢉ”ΛදݱͰ͖Δσʔλܕ
case Ϋϥεʂ
Slide 82
Slide 82 text
Option ܕΛ͏
val person: Option[Person] = map.get(“tom”)
person match {
case Some(p) => println(p.name)
case None => println(“no value!”)
}
ύλʔϯϚονͰ
҆શʹΛऔΓग़ͤΔ
Option ܕ
Slide 83
Slide 83 text
person match {
case Some(p) => println p.name
// If you forget ‘case None =>’...
}
warning: match may not be exhaustive.
It would fail on the following input: None
person match {
^
ίϯύΠϥ͕
ϛεΛݟ͚ͭͯܯࠂͯ͘͠ΕΔʂ
Option ܕ
͏͔ͬΓ None Λ
Εͯ…
ίϯύΠϥ:
ʮNone ͷఆ͕ٛແ͘ͳ͍ʁʯ
Slide 84
Slide 84 text
ίϨΫγϣϯԋࢉͱͷΈ߹Θͤ
person map { p =>
p.name // Someͷ͚࣌ͩΛऔग़͠
} orElse {
Some(“no value!”) // Noneͷ͚࣌ͩஔ͖͑Δ
} foreach { name =>
println(name) // Someͷ͚࣌ͩग़ྗ
}
ώϯτ: Option ཁૉ͕ 0 ͔ 1 ͷ List
Option ܕ
Ϧετͱಉ͡ϝιου…ʁ