이번에는 좀 더 심화 내용을 복습한다.
공부 한 내용은 코드 블럭 안에 주석으로 달았다.
package part1recap
import scala.concurrent.Future
object AdvancedRecap extends App {
// partial functions 부분 함수는 주어진 입력 영역의 하위 집합에서만 작동하는 함수
// 값 1, 2, 5에만 작동하고 다른 것에 대해선 예외를 발생시킴
// 부분 함수가 일반 함수의 확장이라면, 컬렉션이 부분 함수에서도 작동한다
val partialFunction: PartialFunction[Int, Int] = {
case 1 => 42
case 2 => 65
case 5 => 999
}
// 위와 동일한 부분 함수
val pf = (x: Int) => x match {
case 1 => 42
case 2 => 65
case 5 => 999
}
val function: (Int => Int) = partialFunction
// 앞으로 많이 사용할 형태
val modifiedList = List(1,2,3).map {
case 1 => 42
case _ => 0
}
// lifting
val lifted = partialFunction.lift // total function Int => Option[Int]
lifted(2) // Some(65)
lifted(5000) // None
// orElse 부 함수 연결
val pfChain = partialFunction.orElse[Int, Int] {
case 60 => 9000
}
pfChain(5) // 999 per partialFunction
pfChain(60) // 9000
pfChain(457) // throw a MatchError
// type aliases 유형 별칭
type ReceiveFunction = PartialFunction[Any, Unit]
def receive: ReceiveFunction = {
case 1 => println("hello")
case _ => println("confused....")
}
// implicits 스칼라는 암시적이다
implicit val timeout = 3000 // timeout 은 밀리초
def setTimeout(f: () => Unit)(implicit timeout: Int) = f()
setTimeout(() => println("timeout"))// extra parameter list omitted
// implicit conversions
// 1) implicit defs
case class Person(name: String) {
def greet = s"Hi, my name is $name"
}
implicit def fromStringToPerson(string: String): Person = Person(string)
"Peter".greet
// fromStringToPerson("Peter").greet - automatically by the compiler
// 2) implicit classes
implicit class Dog(name: String) {
def bark = println("bark!")
}
"Lassie".bark
// new Dog("Lassie").bark - automatically done by the compiler
// organize
// local scope
implicit val inverseOrdering: Ordering[Int] = Ordering.fromLessThan(_ > _)
List(1,2,3).sorted // List(3,2,1)
// 암시적 매개변수의 값은 어떤 특정 로컬 범위(혹은 해당 범위)에서 가져옴
// 로컬 범위 : 암시적 매개변수가 포함된 메서드가 호출되는 전체 범위
// 사용자가 이 범위에서 암시적 값을 정의하거나 가져올 수 있음.
// 즉, 암시적 매개변수는 그 값이 어떤 특정 범위에서 자동으로 주입됨
// imported scope
// 아래의 임포트 문이 없으면 컴파일러가 'executor' 매개변수에 대한 암시적 값이 없다고 경고함
// 임포트 문 덕분에 암시적 값을 futures의 apply 메소드에 주입할 수 있다고 판단함
import scala.concurrent.ExecutionContext.Implicits.global
val future = Future {
println("hello, future")
}
// companion objects of the types included in the call
// 컴파일러가 암시적 값을 가져오는 순서 1. 로컬 범위 2. 가져온 범위 3. 호출에 포함된 유형의 동반 객체
object Person {
implicit val personOrdering: Ordering[Person] = Ordering.fromLessThan((a, b) => a.name.compareTo(b.name) < 0)
}
// 메소드 호출에 관여하는 유형의 동반 객체에 있기 때문에 컴파일러가 암시적 값을 가져옴
List(Person("Bob"), Person("Alice")).sorted
// List(Person(Alice), Person(Bob))
}
++
스칼라로 아카를 사용하기 위해서 특히 중요한 부분 :
부분 함수
Lift, orElse 등의 컬렉션
타입 별칭
암시적 동작 방식, 암시적 값과 클래스와 메소드의 변환
컴파일러가 암시적 값을 가져오는 순서
모든 것이 단일 스레드 모델에서 발생함