9. 9
03
import java.util.{Date, Locale}
import java.text.DateFormat
import java.text.DateFormat._
object FrenchDate {
def main(args: Array[String]) {
val now = new Date
val df = getDateInstance(LONG, Locale.FRANCE)
println(df format now)
}
}
French Date
df.format(now)
20. 20
06
케이스 클래스
간단 덧셈 계산기 만들기 ex : 1+1 , (x+x)+(7+y)
abstract class Tree
case class Sum(l: Tree, r: Tree) extends Tree
case class Var(n: String) extends Tree
case class Const(v: Int) extends Tree
인스턴스를 생성 할 때 new 키워드를 생략 할 수 있다. 다른 말
로, new Const(5)라 쓰는 대신 Const(5)라 쓰면 된다.
생성자 파라미터들에 대한 getter 함수가 자동으로 정의된다. 다
른 말로, 클래스 Const의 인스턴스 c에 있는 생성자 파라미터 v의
값은 c.v로 접근 가능하다.
21. 21
06
케이스 클래스
간단 덧셈 계산기 만들기 ex : 1+1 , (x+x)+(7+y)
abstract class Tree
case class Sum(l: Tree, r: Tree) extends Tree
case class Var(n: String) extends Tree
case class Const(v: Int) extends Tree
함수 equals와 hashCode도 공짜로 제공된다. 이 함수들은 레퍼런스
의 동일함 보다 구조의 동일함을 확인 하도록 구현되어 있다. 다른 말
로, 생성 된 곳이 다르더라도 각각의 생성자 파라미터 값이 같다면 같
은 것으로 여긴다.
22. 22
05
abstract class Tree
case class Sum(l: Tree, r: Tree) extends Tree
case class Var(n: String) extends Tree
case class Const(v: Int) extends Tree
함수 toString에 대한 기본적 구현이 제공된다. 이 기본적인 구현은
“값이 생성 될 때”의 형태를 출력한다. 예를 들어 x+1의 트리 표현
을 출력 한다면 Sum(Var(x),Const(1))이 된다.
케이스 클래스들의 인스턴스는 패턴 매칭을 통해 따로 사용 될 수
있다.
케이스 클래스
간단 덧셈 계산기 만들기 ex : 1+1 , (x+x)+(7+y)
23. 23
06 패턴 매칭
{ case "x" => 5 case "y" => 7 }
type Environment = String => Int
산술 표현식을 나타낼 타입 완성 (Tree, Sum, Var, Const)
Environment 를 정의하자. 어떻게???
아래와 같이 해시맵 형태로 만들어 보자.
스칼라에서는 이렇게 간단하게 정의 가능
Environment 는 type 키워드를 사용하여 이렇게 정의하자
“문자열이 오면 정수형으로 바꿔라” 라는 의미
24. 24
06 패턴 매칭
def eval(t: Tree, env: Environment): Int =
t match {
case Sum(l, r) => eval(l, env) + eval(r, env)
case Var(n) => env(n)
case Const(v) => v
}
이제 실제로 계산 하는 함수를 정의하자
요만큼이 match 키워드를 사용한 패턴매칭
25. 25
06 패턴 매칭
def eval(t: Tree, env: Environment): Int =
t match {
case Sum(l, r) => eval(l, env) + eval(r, env)
case Var(n) => env(n)
case Const(v) => v
}
eval 을 Tree 의 하위 클래스의 멤버 함수 로 정의해도 될 것 같은데??
그렇게 해도 된다.
패턴매칭을 사용하느냐?
멤버함수를 사용하느냐?
는 개발자 취향 문제!!!!
But! 확장성을 고려한다면…
26. 26
06 패턴 매칭 .VS. 멤버 함수
멤버 함수를 사용하면
단지 Tree에 대한 하위 클래스를 새롭게 정의 함으로
새로운 노드를 추가하기 쉽다.
반면에 트리에 대한 새로운 연산을 추가하는 작업이 고되다.
새로운 연산을 추가하기 위해서는 Tree의 모든 하위 클래스를
변경해야 하기 때문이다.
패턴 매칭을 사용하면 상황이 반대가 된다.
새로운 노드를 추가하려면 트리에 대해 패턴 매칭을 수행하는
모든 함수들을 새로운 노드도 고려하도록 변경해야 한다.
반면에 새로운 연산을 추가하는 것은 쉽다.
그냥 새로운 독립적인 함수를 만들면 된다.
27. 27
06 패턴 매칭
1. 더하기 표현식은 좌변과 우변을 더한 것이다
2. 변수 v에 대한 심볼 추출은 우리가 추출하기 원하는 심볼과 관련이
있다면 1이 되고 그 외의 경우 0 이 된다
3. 상수에 대한 심볼 추출 값은 0 이다.
def derive(t: Tree, v: String): Tree = t match {
case Sum(l, r) => Sum(derive(l, v), derive(r, v))
case Var(n) if (v == n) => Const(1)
case _ => Const(0)
} 가드 : if 키워드 뒤에 오는
표현식을 뜻함,
추가 조건 부여그 밖의 모든 경우
28. 28
06 테스트 코드 작성
def main(args: Array[String]) {
val exp: Tree = Sum(Sum(Var("x"), Var("x")), Sum(Const(7), Var("y")))
val env: Environment = { case "x" => 5 case "y" => 7 }
println("Expression: " + exp)
println("Evaluation with x=5, y=7: " + eval(exp, env))
println("Derivative relative to x:n " + derive(exp, "x"))
println("Derivative relative to y:n " + derive(exp, "y"))
}
출력 결과 :
Expression: Sum(Sum(Var(x),Var(x)),Sum(Const(7),Var(y)))
Evaluation with x=5, y=7: 24
Derivative relative to x:
Sum(Sum(Const(1),Const(1)),Sum(Const(0),Const(0)))
Derivative relative to y:
Sum(Sum(Const(0),Const(0)),Sum(Const(0),Const(1)))
30. 30
07 트레잇(trait)
코드를 가질 수 있는 인터페이스
Scala 에서 클래스가 트레잇을 상속한다면?
트레잇의 인터페이스를 구현하라
And 트레잇에 구현된 모든 코드 다 니꺼!!
31. 31
07
trait Ord
객체들의 순서를 비교하는 기능( < , <=, ==, !=, >, >= )
<,==만구현되면모든기능이구현됨
trait Ord {
def < (that: Any): Boolean
def <=(that: Any): Boolean = (this < that) || (this == that)
def > (that: Any): Boolean = !(this <= that)
def >=(that: Any): Boolean = !(this < that)
}
Java 의 Comparable 인터페이스와 같은 것!
Ord 에는 세가지 관계식이 기본으로 구현
하나는 추상함수 ( < )
Any 는 Scala 의 최상위 타입!!!
Java 의 Object 타입과 같으나 int, float 와 같은 기본 타입의 상위타입
이라는 점에서 차이가 있다.
구현된 것
32. 32
07
class Date
그레고리력의 날짜를 나타내는 클래스(크기 비교 가능)
<,==만구현되면모든기능이구현됨
class Date(y: Int, m: Int, d: Int) extends Ord {
def year = y
def month = m
def day = d
override def toString(): String = year + "-" + month + "-" + day
override def equals(that: Any): Boolean =
that.isInstanceOf[Date] && {
val o = that.asInstanceOf[Date]
o.day == day && o.month == month && o.year == year
}
def <(that: Any): Boolean = {
if (!that.isInstanceOf[Date])
error("cannot compare " + that + " and a Date")
val o = that.asInstanceOf[Date]
(year < o.year) ||
(year == o.year && (month < o.month ||
(month == o.month && day < o.day)))
}
}
같다
작다
< , == 만 구현 되면 모든 기능이 구현 됨
34. 34
08 제네릭
Java 1.5 에 제네릭 지원이 부족하여 여러가지 문제 발생(지우개 문제)
제네릭이 먼지 알려면 여기 :
http://opentutorials.org/module/516/6237
지우개 문제가 먼지 알려면 여기 :
http://newstars.tistory.com/33
제네릭 함(Genericty) 이란
코드를 타입에 대하여 파라미터화 할 수 있는 능력
35. 35
08 링크드 리스트 만들어 보기
[Java]
리스트의 원소 타입을 뭐로 하지 ? Int, Double???
불가능 그냥 Object 로 퉁!
But, int, long, float 같은 기본 타입에서는 정상 동작하지 않음
프로그래머 님이 알아서 해주세요.
[Scala]
제네릭 클래스와 제네릭 함수를 지원
36. 36
08 링크드 리스트 만들어 보기
[Java]
리스트의 원소 타입을 뭐로 하지 ? Int, Double???
불가능 그냥 Object 로 퉁!
But, int, long, float 같은 기본 타입에서는 정상 동작하지 않음
프로그래머 님이 알아서 해주세요.
[Scala]
제네릭 클래스와 제네릭 함수를 지원
37. 37
08
class Reference
간단한 데이터 저장 구조 클래스
class Reference[T] {
private var contents: T = _
def set(value: T) { contents = value }
def get: T = contents
}
얘가 제네릭 하기 위해 쓰는 타입 파라미터,
매크로 문자 같은 거임
요기 조기 막 쓰임
은 훼이크고 필요한 데서 쓰임
38. 38
08
class Reference
간단한 데이터 저장 구조 클래스
class Reference[T] {
private var contents: T = _
def set(value: T) { contents = value }
def get: T = contents
}
기본 값 이라는 의미
수 타입이라면 0,
Boolean 타입이라면 false
Unit 타입이라면 ()
모든 객체 타입은 null
39. 39
08
object IntegerReference
get 함수의 리턴값을 정수 처럼 사용하기 위해 별도의 캐스팅이 필요 없다.
object IntegerReference {
def main(args: Array[String]) {
val cell = new Reference[Int]
cell.set(13)
println("Reference contains the half of " + (cell.get * 2))
}
}