지금까지 코틀린 기본세팅을 진행했다.
2022.01.29 - [Kotlin] 코틀린 기본개념 - 코틀린이란? 도대체 왜 쓰는가? 특징!
2022.01.28 - [Kotlin] 코틀린 환경설정 - Intellj에서 코틀린 프로젝트 생성하기
2022.01.29 - [Kotiln] Intellj에서 코틀린 코딩컨벤션 Kotlin Style Guide 적용하기
2022.01.30 - [Kotiln] 코틀린 실행하기 - Scratch File (스크래치 파일) 만들기
그리고 간단한 기본문법도 살펴봤다.
2022.01.29 - [Kotiln] 코틀린 기본문법1 (변수선언/함수선언/자료형/반복문/조건문)
2022.01.30 - [Kotiln] 코틀린 기본문법2 (NULL처리 : lateinit/lazy/!!/?/?.)
2022.01.30 - [Kotiln] 코틀린 기본문법3 (클래스와 컬렉션: List/Map/Set)
이번엔 조금 깊게 심화문법으로 몇가지를 더 살펴볼 예정이다.
함수형프로그래밍
기본적으로 코틀린은 함수형 프로그래밍을 지원하기 때문에 모듈을 함수로 구현할수 있다.
그러다보니까 기본 라이브러리 함수들이 몇개 있다.
확장함수 (extension functions)
기존에 정의된 클래스에 함수를 추가하는 기능이다.
보통 자기가 만든 클래스에 함수를 추가하려면 [클래스명].[함수명]을 할 수 있지만,
기존에 정의된 클래스에 함수를 추가하기 위해선 확장함수를 정의해야한다.
https://codechacha.com/ko/kotlin-extension-functions/
고차함수 (higer-order functins)
함수의 인자로 함수를 넘기거나 함수를 리턴할 수 있는 기능이다.
val hello: () -> String = {"hello world"}
fun returnParamFunc(func: ()->String): () -> String {
return func
}
fun main(args: Array<String>) {
val returned = returnParamFunc(hello) //hello함수 인자 -> returnParamFunc 호출
print("${returned()}")
}
인자로 함수를 넘길때 함수의 타입을 명시해야한다. 예를 들어, func: ()->String 처럼 함수의 타입이 string.
->를 기준으로 왼쪽은 파라미터(인자), 오른쪽은 리턴값을 의미한다.
리턴값이 없으면 Unit으로 표기
Scope functions
자바에는 없지만 코틀린에서 제공하는 기본라이브러리 함수 중에 하나로 let,run.with,apply,also 함수가 있다.
이들은 Scope functions 이라고 불리며 객체에 쉽게 접근할 수 있도록 해주는 함수이다.
덕분에 코드가 간결해지고 가독성이 높아진다.
Scope functions 을 사용할때는 리시버와 람다함수를 넘겨준다.
아래의 코드에서 person을 리시버라고 하고, let이후 {}를 람다함수라고 한다.
그래서 람다함수에서는 person객체에 접근할 수 있다.
함수명 | 객체 접근방법 | 리턴형태 | 확장함수 가능여부 |
let | it | 람다식 결과 반환(block) | 가능 |
also | it | 객체.also(it) (object) | 가능 |
with | this | 인자로만 결과반환 | 불가능 |
run | this | 람다식 결과 반환(block) | 가능 |
run | this | 인자로도 쓰임 | 불가능 |
apply | this | 객체.apply(this) (object) | 가능 |
let() 함수
it으로 리시버에 접근하고, 람다함수의 마지막결과를 리턴한다.
블록에 자기자신을 인수로 전달하고 수행된 결과를 반환한다. 인수로 전달되는 자기자신은 it으로 참조한다.
let()함수는 아래처럼 한번에 여러함수를 호출할때 사용한다.
val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let {
println(it)
// it의미 : numbers 리스트 아이템들의 length
// 즉, it이 3이상인 것들만 it(length)출력
//출력 : [5,4,4]
}
또는 ?키워드랑 같이 쓰이면서 NULL이 아닐때만 리시버가 동작하도록 할때 사용한다.
val str: String? = "Hello"
val length = str?.let {
println("let() called on $it")
it.length
}
// 실행 결과 : 5
println("result: $length")
also() 함수
it으로 리시버에 접근하고, 람다함수의 마지막결과를 리턴한다.
let()과 기능은 비슷하지만, apply처럼 객체의 상태를 변화시키고 그 객체를 다시 반환할때 사용한다.
리시버 스스로를 리턴하기 때문에 연속적으로 객체를 호출할수 있다.
val numbers = mutableListOf("one", "two", "three")
numbers
.also { println("The list elements before adding new one: $it") }
.add("four")
let()과 also()가 동시에 사용하게 될 경우 아래처럼 쓰일수 있다.
let()은 식의 결과를 반환하고, 그 결과를 다시 also()에게 넘겨서 상태를 변화시킨다.
fun makedir(path:String):File {
val result = File(path)
result.mkdidrs()
return result
}
fun makeDir(path:String)=path.let{File(it)}.also(it.mkdirs()}
With() 함수
this로 리시버에 접근하고, 람다함수의 마지막 결과를 리턴한다.
인수로 전달되는 자기자신을 this로 참조한다. 이렇게 this 키워드를 생략할 수도 있고, 리턴값 생략을 권장한다.
let은 리시버의 확장함수로 쓰이지만 with은 그렇지 않다. 그래 리시버객체는 with(리시버객체){람다함수}로 인자로만 전달할 수 있다.
val numbers = mutableListOf("one", "two", "three")
val firstAndLast = with(numbers) {
"The first element is ${first()}," +
" the last element is ${last()}"
}
println(firstAndLast)
Run() 함수
with과 마찬가지로 this로 리시버에 접근하고, 람다함수의 마지막 결과를 리턴한다.
하지만 with과 다르게 확장함수로 쓸 수 있다. 그래서 리시버객체를 리시버객체.run{람다함수}처럼 함수처럼 쓸 수 있다.
run()함수는 람다함수에서 여러값을 초기화하고, 리턴값을 어떤 객체의 초기값으로 사용한다.
//객체에서 호출하는 방식으로 사용가능
val service = MultiportService("https://example.kotlinlang.org", 80)
val result = service.run {
port = 8080
query(prepareRequest() + " to port $port")
}
위와 같은 내용을 let()함수로 똑같이 쓸 수도 있는데 차이점이라면 run()함수는 굳이 확장함수로 사용하지 않을때도 사용할수 있다.
그래서 Run()함수는 익명함수처럼 사용하거나 객체에서 호출하는 방법 모두 제공한다.
//익명함수처럼 사용가능
val hexNumberRegex = run {
val digits = "0-9"
val hexDigits = "A-Fa-f"
val sign = "+-"
Regex("[$sign]?[$digits$hexDigits]+")
}
for (match in hexNumberRegex.findAll("+1234 -FFFF not-a-number")) {
println(match.value)
}
apply()함수
with,run과 마찬가지로 this로 리시버에 접근하고, 람다함수의 마지막 결과를 리턴한다.
객체의 상태를 변화시키고 그 객체를 다시 반환할때 사용한다.
val adam = Person("Adam").apply {
age = 32
city = "London"
}
//person객체의 age,city과 변경된채 리턴된다.
참고
https://codechacha.com/ko/kotlin-standard-library-functions/
https://junyoung-developer.tistory.com/134?category=930228
https://sabarada.tistory.com/172?category=941106
'🍃 Language > Kotiln' 카테고리의 다른 글
[Kotlin] 코틀린 심화문법4 (object와 companion object) (0) | 2022.02.04 |
---|---|
[Kotlin] 코틀린 심화문법3 (data class와 open class) (0) | 2022.02.03 |
[Kotlin] 코틀린 코루틴 개념과 basics - 새차원 강의1,2요약 (0) | 2022.01.31 |
[Kotlin] 코틀린 심화문법1 (람다식:lambda expression) (0) | 2022.01.31 |
[Kotlin] 코틀린 기본문법3 (클래스와 컬렉션: List/Map/Set) (0) | 2022.01.30 |
[Kotlin] 코틀린 기본문법2 (NULL처리 : lateinit/lazy/!!/?/?.) (0) | 2022.01.30 |