This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| language:scala [2020/08/17 13:02] – [Bounded Type] 설명 수정 ledyx | language:scala [2021/03/24 08:18] (current) – [Command Line] 프로젝트 생성/배포 내용 보강 ledyx | ||
|---|---|---|---|
| Line 13: | Line 13: | ||
| https:// | https:// | ||
| - | * SBT (Scala Build Tools) | + | === SBT (Scala Build Tools) |
| Scala의 Ant/ | Scala의 Ant/ | ||
| + | |||
| + | ==== Create templates ==== | ||
| + | |||
| + | https:// | ||
| <sxh shell> | <sxh shell> | ||
| - | # 생성 | + | sbt new scala/ |
| - | sbt [Project Name] | + | </ |
| + | |||
| + | ==== Fat Jar ==== | ||
| + | |||
| + | https:// | ||
| + | |||
| + | <sxh shell> | ||
| # Build (Fat Jar 생성) | # Build (Fat Jar 생성) | ||
| ## build.sbt에 | ## build.sbt에 | ||
| - | ## addSbtPlugin(" | + | ## addSbtPlugin(" |
| ## 추가 필요 | ## 추가 필요 | ||
| ### 생성된 jar 위치 : target/ | ### 생성된 jar 위치 : target/ | ||
| - | sbt assemblyty | + | sbt assembly |
| </ | </ | ||
| - | * Scala Binaries (선택 사항) | + | |
| + | === Scala Binaries (선택 사항) | ||
| * REPL(scala), | * REPL(scala), | ||
| Line 117: | Line 128: | ||
| 식별자 규칙 및 관례적 명명법 서술. | 식별자 규칙 및 관례적 명명법 서술. | ||
| - | * 연산자 정의(Operator Defination) Method와 암시적 변환([[language: | + | * 연산자 정의(Operator Defination) Method와 암시적 변환([[language: |
| Line 434: | Line 445: | ||
| ==== for-yield ==== | ==== for-yield ==== | ||
| - | < | + | < |
| <code scala> | <code scala> | ||
| Line 985: | Line 996: | ||
| ==== Companion object ==== | ==== Companion object ==== | ||
| - | 어떤 class **이름**이 같은 object. 그 피대상인 class는 " | + | 어떤 class **이름**이 같은 object. 그 피대상인 class는 " |
| 이 때, object의 field들이 " | 이 때, object의 field들이 " | ||
| Line 1236: | Line 1247: | ||
| == Bounded Type == | == Bounded Type == | ||
| - | 특정 Class나 거의 Sub type 또는 Base type으로 **<fc red> | + | Type Parameter를 |
| === Upper bound === | === Upper bound === | ||
| Line 1281: | Line 1292: | ||
| 타입 가변성(Type variance)은 Type parameter가 Base type이나 Sub type을 충족하도록 적응하는 방법을 지정한다. | 타입 가변성(Type variance)은 Type parameter가 Base type이나 Sub type을 충족하도록 적응하는 방법을 지정한다. | ||
| - | === Invariance === | + | |< |
| - | + | ^ | |
| - | 무공변성. | + | | +T | ? extends T | Covariance (공변성) |
| + | | -T | ||
| + | | | ||
| - | Type parameter의 기본값. Type-parameterized class의 Instance는 오직 같은 Parameterized | + | * Effective Java에서 나오는 [[https:// |
| + | * Producer는 getter, Consumer는 setter | ||
| + | * Scala의 [[https:// | ||
| + | * 첫번째 인자 **-T1**는 Producer, 두번째 인자 **+R**는 반환값으로 Consumer. | ||
| + | * 반환해야 하는(생산하는) 값이 Super type인데, 인자로 받은(제공하는) 값이 Sub type이면 Super type의 Method를 | ||
| + | * 이런 이유로 T1은 동등한 레벨의 타입이거나 상위 타입(Super type)이어야 한다. | ||
| + | * " | ||
| <sxh scala> | <sxh scala> | ||
| - | class Item[A] | + | // https:// |
| - | class Person | + | class CSuper |
| - | class Employee | + | class C |
| - | class HomeMinusEmployee | + | class CSub extends |
| - | + | ||
| - | + | ||
| - | object Practice extends App { | + | |
| - | // Okay! | + | |
| - | val p: Person = new Employee() | + | |
| - | val i1: Item[Person] | + | |
| + | object AbsTypes extends App { | ||
| + | // 추상적인 것 -> 구체적인 것 | ||
| + | val f1: C => C = (c: C) => new C | ||
| + | val f2: C => C = (c: CSuper) => new CSub | ||
| + | val f3: C => C = (c: CSuper) => new C | ||
| + | val f4: C => C = (c: C) => new CSub | ||
| + | | ||
| // Error! | // Error! | ||
| - | val i2: Item[Person] | + | |
| + | | ||
| + | */ | ||
| + | | ||
| } | } | ||
| </ | </ | ||
| - | === Covariance === | ||
| - | 공변성. | + | = Abstract types = |
| - | Type parameter가 부모 Type으로 변할 수 있는 성질. (Sub parameterized-type → Base parameterized-type) Type parameter 앞에 **+**를 붙인다. | + | https:// |
| - | <sxh scala ; highlight: [1]> | + | <sxh scala ; highlight:[7, |
| - | class Item[+A] | + | import java.io._ |
| + | import scala.io.Source | ||
| - | class Person | + | // https:// |
| - | class Employee extends Person | + | // 위 소스를 응용한 예제 |
| - | class HomeMinusEmployee extends Employee | + | abstract |
| + | type In // 구체적인 타입을 지정하지 않음. | ||
| + | val source: In // 바로 위에서 지정한 Type인 " | ||
| + | def read: String | ||
| + | } | ||
| - | object Practice extends App { | + | class StringBulkReader |
| - | // Okay! | + | (val source: String) |
| - | | + | |
| - | | + | |
| - | | + | |
| - | val i2: Item[Person] | + | |
| } | } | ||
| - | </ | ||
| + | class FileBulkReader | ||
| + | (val source: File) // 추상 타입의 실질 타입 정의 | ||
| + | extends BulkReader { | ||
| + | type In = File // 추상 타입 구체화 | ||
| - | === Contravariance === | + | override def read: String |
| + | val source1 | ||
| + | try source1.mkString finally source1.close() | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| - | 반공변성. | + | == Parameterized types vs. Abstract types == |
| + | 어떤 상황에서 무엇이 적절한가? | ||
| + | |||
| + | * Parameterized types : Type parameter가 Parameterized types와 관련이 없는 경우 | ||
| + | * List[A]에서 A는 String, Int 무엇이든 상관 없음. | ||
| + | | ||
| + | * Abstract types : 타입 멤버가 객체의 **동작**과 일치하는 경우 | ||
| + | * 위 예시를 보면 " | ||
| Line 1345: | Line 1386: | ||
| - | <sxh scala ; > | + | <sxh scala> |
| object Printer { | object Printer { | ||
| def print(num: Double)(implicit format: String) = println(format.format(num)) | def print(num: Double)(implicit format: String) = println(format.format(num)) | ||