This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| kotlin [2019/01/03 17:08] – [기타 유의 사항] ledyx | kotlin [2021/02/07 03:15] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | = Kotlin = | + | ~~REDIRECT>language:kotlin~~ |
| - | + | ||
| - | * 기본적으로 Java를 다뤄봤다는 전제하에 실용적인 측면으로만 기술. | + | |
| - | + | ||
| - | {{tag>Language Scala JVM Object_Oriented_Programming Functional_Programming}} | + | |
| - | + | ||
| - | = 기본 = | + | |
| - | + | ||
| - | <sxh kotlin> | + | |
| - | // data를 붙이면 toString(), equals(), hashCode(), copy() Method 생성 | + | |
| - | // 기본적으로 모든 변수는 null을 허용하지 않기 때문에, C#처럼 " | + | |
| - | // C#처럼 default value를 지정할 수 있음. | + | |
| - | // val은 Scala처럼 Immutable, var는 Mutable. | + | |
| - | // Custom Accessor는 C#처럼 작성. 아래는 getter의 예시. | + | |
| - | data class Person(val name: String, val age: Int? = null, val job: String = " | + | |
| - | val isDeveloper: | + | |
| - | get() = job == " | + | |
| - | } | + | |
| - | + | ||
| - | // 함수 내용이 한 줄인 경우 " | + | |
| - | // it은 Scala나 Clojure의 " | + | |
| - | //"?:" | + | |
| - | fun getOldest(persons: | + | |
| - | + | ||
| - | // main 함수를 작성하는데 class가 필요하지 않다. | + | |
| - | fun main(args: Array< | + | |
| - | val person1 = Person(" | + | |
| - | // Nullable로 선언했기에 age는 생략 가능 | + | |
| - | val person2 = Person(" | + | |
| - | + | ||
| - | // 이름을 붙인 argument | + | |
| - | // 단, Java로 작성된 Code는 사용할 수 없음. 즉, Android에서 API 호출시 사용할 수 없음. | + | |
| - | val person3 = Person(age = 22, name = " | + | |
| - | + | ||
| - | //list 생성. 모든 Collection은 ...Of로 생성 가능. | + | |
| - | val persons = listOf(person1, | + | |
| - | val oldest = getOldest(persons) | + | |
| - | + | ||
| - | // 문자열 Template 지원. 식(Expression)이 아닌 경우 {} 생략 가능. | + | |
| - | println(" | + | |
| - | println(persons.filter { it.isDeveloper }) | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | oldest : Person(name=Jake, | + | |
| - | [Person(name=Jake, | + | |
| - | </ | + | |
| - | + | ||
| - | == High-Order Functions 시험 == | + | |
| - | + | ||
| - | https:// | + | |
| - | + | ||
| - | 아래 예제처럼 Kotlin은 함수를 first-class로 취급하므로 Functional Programming의 기본 특성을 만족한다. (함수를 인자로 받고, 함수를 반환할 수 있는 특성) | + | |
| - | + | ||
| - | < | + | |
| - | // Type만을 지정하기 위한 빈 Interface 생성. 상속은 ":" | + | |
| - | interface Event | + | |
| - | data class KeyEvent(val value: String): Event | + | |
| - | fun onKeyDown(f: | + | |
| - | + | ||
| - | fun main(args: Array< | + | |
| - | // onKeyDown { event -> println(event) } 와 동치. | + | |
| - | onKeyDown { println(it) } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | KeyEvent(value=Hello, | + | |
| - | </ | + | |
| - | + | ||
| - | = Control Flow = | + | |
| - | + | ||
| - | https:// | + | |
| - | + | ||
| - | if, while/do while은 동일하므로 생략. | + | |
| - | + | ||
| - | == when == | + | |
| - | + | ||
| - | <sxh kotlin> | + | |
| - | interface Event | + | |
| - | data class KeyEvent(val value: String): Event | + | |
| - | data class MouseEvent(val value: String): Event | + | |
| - | + | ||
| - | fun main(args: Array< | + | |
| - | val eventControlFlow = { | + | |
| - | event: Event -> | + | |
| - | when (event) { | + | |
| - | is KeyEvent -> println(" | + | |
| - | is MouseEvent -> println(" | + | |
| - | else -> println(" | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | // 인자가 없는 형태로도 사용 가능. 이 경우 Matching 대상이 계속 Instance를 생성하는 경우 사용. | + | |
| - | /* val eventControlFlow = { | + | |
| - | event: Event -> | + | |
| - | when { | + | |
| - | event is KeyEvent -> println(" | + | |
| - | event is MouseEvent -> println(" | + | |
| - | else -> println(" | + | |
| - | } | + | |
| - | } */ | + | |
| - | + | ||
| - | eventControlFlow(KeyEvent(" | + | |
| - | eventControlFlow(MouseEvent(" | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | Key event! foo | + | |
| - | Mouse event! bar | + | |
| - | </ | + | |
| - | + | ||
| - | == for == | + | |
| - | foreach만 존재. | + | |
| - | + | ||
| - | <sxh kotlin> | + | |
| - | fun main(args: Array< | + | |
| - | + | ||
| - | // in은 infix가 붙은 함수로 중위표현식 가능. | + | |
| - | // in은 Collections 혹은 Range의 원소 검사. | + | |
| - | val test = " | + | |
| - | println(test) | + | |
| - | + | ||
| - | for (i in 1..10) { | + | |
| - | print(" | + | |
| - | } | + | |
| - | + | ||
| - | println() | + | |
| - | + | ||
| - | for (i in 10 downTo 1) { | + | |
| - | print(" | + | |
| - | } | + | |
| - | + | ||
| - | println() | + | |
| - | + | ||
| - | for (i in 10 downTo 1 step 2) { | + | |
| - | print(" | + | |
| - | } | + | |
| - | + | ||
| - | println() | + | |
| - | + | ||
| - | val size = 10 | + | |
| - | for (i in 0 until size) { | + | |
| - | print(" | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | true | + | |
| - | 1 2 3 4 5 6 7 8 9 10 | + | |
| - | 10 9 8 7 6 5 4 3 2 1 | + | |
| - | 10 8 6 4 2 | + | |
| - | 0 1 2 3 4 5 6 7 8 9 | + | |
| - | </ | + | |
| - | + | ||
| - | === Destructuring ==== | + | |
| - | + | ||
| - | <sxh kotlin> | + | |
| - | data class Person(val name: String, val age: Int? = null) | + | |
| - | + | ||
| - | fun main(args: Array< | + | |
| - | val l = arrayListOf< | + | |
| - | l.add(Person(" | + | |
| - | l.add(Person(" | + | |
| - | l.add(Person(" | + | |
| - | + | ||
| - | // Destructuring | + | |
| - | for((age, name) in l) { | + | |
| - | println(" | + | |
| - | } | + | |
| - | + | ||
| - | println() | + | |
| - | + | ||
| - | for((index, element) in l.withIndex()) { | + | |
| - | // Kotlin은 element에 대해서 Nested Destructuring 을 지원하지 않기 때문에 변수를 이용하여 Destructuring. | + | |
| - | val (name, age) = element | + | |
| - | println(" | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | 11 Jake | + | |
| - | 23 Luke | + | |
| - | 21 Nina | + | |
| - | 0 Jake 11 | + | |
| - | 1 Luke 23 | + | |
| - | 2 Nina 21 | + | |
| - | </ | + | |
| - | + | ||
| - | + | ||
| - | = Collections = | + | |
| - | 기본적으로 ...Of 형태로 생성 가능. | + | |
| - | + | ||
| - | == Map == | + | |
| - | + | ||
| - | <sxh kotlin> | + | |
| - | fun main(args: Array< | + | |
| - | val map = hashMapOf(1 to " | + | |
| - | map[3] = " | + | |
| - | + | ||
| - | for ((key, value) in map) { | + | |
| - | println(" | + | |
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | 1 one | + | |
| - | 2 two | + | |
| - | 3 three | + | |
| - | </ | + | |
| - | + | ||
| - | + | ||
| - | = Functions = | + | |
| - | == Extension Functions == | + | |
| - | + | ||
| - | 이미 존재하는 Class에 함수 확장. Static Method 호출에 대한 Syntatic sugar. 이를 이용하더라도 private/ | + | |
| - | + | ||
| - | <sxh kotlin ; title: | + | |
| - | // 다른 파일에서 사용하려면 package 선언. 임의 이름으로 선언 가능. | + | |
| - | package myextension | + | |
| - | + | ||
| - | // 기존에 존재하는 List에 filterByOdd() 함수 확장. | + | |
| - | fun List< | + | |
| - | </ | + | |
| - | + | ||
| - | <sxh kotlin ; title: | + | |
| - | import myextension.filterByOdd | + | |
| - | + | ||
| - | fun main(args: Array< | + | |
| - | (1..10).toList().filterByOdd().forEach { println(it) } | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | = 기타 유의 사항 = | + | |
| - | + | ||
| - | == Class == | + | |
| - | * 모든 Class는 final로 상속 불가이다. 상속 허용을 하려면 " | + | |
| - | + | ||
| - | + | ||
| - | == Enum == | + | |
| - | * 선언은 "enum class CLASSNAME" | + | |
| - | * 함수를 내장하는 경우 마지막 enum 값에 ";" | + | |
| - | + | ||
| - | + | ||
| - | == Functions == | + | |
| - | * 이름 있는 인자는 Java로 작성된 Code에서 사용할 수 없다. 즉, Android의 API에서 사용할 수 없다. | + | |
| - | * Java에서 Default Parameter 값이 적용된 함수를 이용하려면 " | + | |
| - | + | ||
| - | == JVM Interop == | + | |
| - | * 다른 JVM 언어에서 Kotlin 파일의 함수를 호출하려면 접미사가 " | + | |
| - | + | ||