Kotlin function
코틀린 함수(Kotlin Method)
- 코틀린 함수 기본 형태
- fun을이용해서 정의, void를 사용하지 않음, 리턴타입의 위치가 틀림
-
코틀린 함수 예제
fun 함수명(변수) { } fun 함수명(변수): 리턴타입 { return 값 } private fun loadRawData() = runSubtask("parse: ${file.name}") { try { file .readLines(charset) .map { line -> parser.parse(line) } .filter { rawFilter.filter(it) } .map { line -> line.toTypedArray() } } catch (ex: FileNotFoundException) { log.error("파일이 존재하지 않습니다 - $file", ex) null } }
- 코틀린에서는 함수를 클래스 안에 선언할 필요가 없음
- 파라미터에 default를 지정하여 함수 overloading을 대신할 수 있음
- 파라미터 이름을 지정하여 호출할 수 있음
- default가 있는 경우 이름을 지정하지 않는 경우 순서대로 뒤에 있는 것을 생략 가능
- default가 있는 경우 이름을 지정하는 경우에는 필요한 것만 지정해서 호출 가능
- 이름을 지정할 경우 java와의 호환성 이슈 생길 수 있음
- java에서는 @JvmOverloads를 붙이면 오버로딩 함수들을 자동으로 생성시켜줌
- Method Override
- java처럼 오버라이드를 위한 명시적인 수정자가 필요하지 않음
- 멤버가 오버라이드 가능하다는 것을 나타내기 위해
open
이라는 키워드 사용 - 오버라이드 하고 있다는 것을 나타내기 위해
override
키워드 사용 - override 표시된 멥버는 자체가 open이므로 하위 클래서에서는 다시 오버라이드 가능
- Property Override (속성 오버라이드) -
범위 지정 함수 : apply, run, with, also, let
- 기능정리 : https://kotlinworld.com/255
- 기능비교 : https://stackoverflow.com/questions/45977011/example-of-when-should-we-use-run-let-apply-also-and-with-on-kotlin
- 범위 지정함수는
수신 객체
와수신 객체 지정 람다
(Lambda with receiver)로 구성 - with()
- 객체 이름 반복 사용을 피하기 위해 사용
- 일반함수는 일반람다, 확장함수는 수신객체지정람다
- 수신객체에 대한 작업 후 마지막 라인 리턴, run과 똑같이 동작 (객체전달방식만 다름)
- run은 확장함수로 사용되고, with는 수신객체 파라미터로 받아 사용
- 보통 run을 사용하고 with는 잘 사용하지 않는 듯…
inline fun <T, R> with(receiver: T, block: T.() -> R): R { return receiver.block() } // examples var r: R = with(T()) { this.foo(); this.toR() } val person: Person = getPerson() with(person) { print(name) print(age) }
- run()
- 매개 변수로 전달된 명시적 수신객체를 암시적 수신 객체로 변환 할때 run()을 사용할수 있음
inline fun <T, R> T.run(block: T.() -> R): R { return block() } // examples var r: R = T().run { this.foo(); this.toR() } // 수행결과를 리턴 val inserted: Boolean = run { // person 과 personDao 의 범위를 제한 합니다. val person: Person = getPerson() val personDao: PersonDao = getPersonDao() personDao.insert(person) // 수행 결과를 반환 합니다. } fun printAge(person: Person) = person.run { print(age) // person 을 수신객체로 변환하여 age 값을 사용합니다. }
- let()
- 널이 될 수 있는 값을 널이 아닌 값만 인자로 넘김
- let를 사용할 때 수신객체가 널인지 검사하기 위해서는 ?.을 사용하여 호출
inline fun <T, R> T.let(block: (T) -> R): R { return block(this) } // examples var r: R = T().let { it.foo(); it.toR() } getNullablePerson()?.let { promote(it) // null 이 아닐때만 실행됩니다. } val driversLicence: Licence? = getNullablePerson()?.let { // nullable personal객체를 nullable driversLicence 객체로 변경합니다. licenceService.getDriversLicence(it) } val person: Person = getPerson() getPersonDao().let { dao -> dao.insert(person) // 변수 dao 의 범위는 이 블록 안 으로 제한 됩니다. }
- apply()
- apply는 also와 마찬가지로 수신 객체를 반환
- 수신 객체 람다 내부에서 수신 객체의 함수를 사용하지 않고 수신 객체 자신을 다시 반환 하려는 경우에 apply 를 사용
inline fun <T> T.apply(block: T.() -> Unit): T { block() return this } // examples var t: T = T().apply { this.foo() } val peter = Person().apply { // apply 의 블록 에서는 오직 프로퍼티 만 사용합니다! name = "Peter" age = 18 }
- also()
- also는 apply 와 마찬가지로 수신 객체를 반환
- 블록 함수가 다른 값을 반환 해야하는 경우에는 also 를 사용할수 없음, 다른 값을 반환하려면 run을 사용
inline fun <T> T.also(block: (T) -> Unit): T { block(this) return this } // examples var t: T = T().also { it.foo() } class Book(author: Person) { val author = author.also { requireNotNull(it.age) print(it.name) } }
Leave a comment