11. 고차 함수와 인라인 함수
1) 고차함수
- 매개변수로 함수를 전달받거나 함수를 반환하는 함수
- 매개변수가 함수 1개일 경우 괄호() 를 생략하고 예약어 형태로 사용 가능
fun function1(func: (Int) -> Int, num: Int) = func(num)
fun function2(func: (Int) -> Int) = func(10)
fun pr(func: (Any) -> Any) = println(func(10))
fun main() {
val a = function1({ it * 10 }, 10)
val b = function2( { it * 10} )
val c = function2 { it * 10}
println("a: $a / b: $b / c: $c")
pr { 10 * 10 }
}
// 결과
a: 100 / b: 100 / c: 100
100
- 매개변수가 여러개일 경우에도 마지막 인수는 괄호 () 밖에서 사용 가능
- 일반 함수에서와 같이 인수가 생략된 경우에 사용할 기본값 지정 가능
typealias SomeType = (Int, String) -> Boolean
fun funcTest(argA: Int, argB: String, argC: SomeType = { i, j -> i.toString() == j }) {
println("argA: $argA /argB: $argB / argC: ${argC(argA, argB)}")
}
fun main() {
funcTest(1, "1")
funcTest(1, "1", { i, j -> i.toString() != j })
funcTest(3, "5") { i, j -> i.toString() != j }
}
// 결과
argA: 1 /argB: 1 / argC: true
argA: 1 /argB: 1 / argC: false
argA: 3 /argB: 5 / argC: true
2) 고차 함수에서의 함수 참조
- 고차 함수 이용시 함수 참조 연산자 :: 이용 가능
fun func1(argFun: (String) -> String) {
val result = argFun("text")
println(result)
}
fun func2(str: String): String{
println(str)
return str.toUpperCase()
}
fun main() {
func1(::func2)
}
// 결과
text
TEXT
3) 익명 함수
- 람다 함수와 달리 return 예약어 사용이 가능하며 반환 타입을 명시적으로 선언 가능
- 주로 고차 함수의 매개변수나 반환값에서 타입을 명시적으로 선언하려고 할 때 이용
val aFunc = fun(name: String): String{
return "Hi $name"
}
fun main() {
println(aFunc("Nick"))
}
// 결과
Hi Nick
4) run() 함수
- run(): 람다 함수를 실행해서 값을 얻을 목적 혹은 객체의 멤버에 접근하기 위해 사용
fun main() {
val num = run {
println("20")
20
}
println(num)
}
// 결과
20
20
class Member(){
var name: String = ""
var age: Int = 0
fun say()= println("Hello $name")
}
fun main() {
val member = Member()
val runrun = member.run {
name = "Nick"
age = 10
say()
"My age: $age"
}
println(runrun)
}
// 결과
Hello Nick
My age: 10
5) apply() 함수
- run() 함수와 사용 목적은 같으나 run() 함수는 함수의 반환값을 반환하고 apply() 함수는 객체 자체를 반환
data class Member(var name: String, var age: Int)
fun main() {
val member = Member("Nick", 10)
val runrun = member.apply {
name = "John"
age = 20
}
println(runrun.toString())
}
// 결과
Member(name=John, age=20)
6) let() 함수
- 전달받은 람다 함수에 매개변수를 전달하고 반환값을 전달받는 함수
- 객체 선언을 줄이려는 목적으로 사용
data class Human constructor(var name: String, var age: Int)
fun printHuman(human: Human):Int {
println("${human.name} / ${human.age}")
return human.age
}
fun main() {
val age = Human("Nick", 10).let { printHuman(it) }
println(age)
}
// 결과
Nick / 10
10
7) with() 함수
- 한 객체의 멤버에 반복해서 접근할 때 객체명 명시 없이 멤버에 접근 가능
fun main() {
val member = Member("Nick", 10)
with(member){
name = "John"
age = 20
}
println(member.toString())
}
// 결과
Member(name=John, age=20)
8) inline 함수와 noinline
- inline 예약어를 사용해서 선언한 함수
- 컴파일 단계에서 함수를 선언하지 않고 정적인 코드로 포함된다.
- 일반 함수에서 사용시 큰 이점이 없으며 고차 함수에서 사용시 성능 문제를 개선할 수 있다.
- 인라인 함수 내의 람다 함수에서 return을 사용할 수 있다.(crossinline 예약어 사용시 return 사용 불가)
- noinline: inline이 선언된 함수에서 noinline 예약어를 이용해서 inline에 포함시키지 않을 함수 매개변수를 명시적으로 선언할 수 있다.
9) 라벨
- 람다 함수에 라벨을 지정 후 해당 라벨만 return 가능
- 라벨을 선언하지 않아도 함수명으로 된 라벨이 자동 추가
fun labelTest(){
println("labelTest Start")
val array = intArrayOf(1,2,3,4,5)
array.forEach {
if(it == 3) return
println(it)
}
println("labelTest Finish")
}
fun main() {
labelTest()
}
// 결과
labelTest Start
1
2
fun labelTest(){
println("labelTest Start")
val array = intArrayOf(1,2,3,4,5)
array.forEach foreach@{
if(it == 3) return@foreach
println(it)
}
println("labelTest Finish")
}
fun main() {
labelTest()
}
// 결과
labelTest Start
1
2
4
5
labelTest Finish
10) 클로저
- 함수가 호출될 때 발생하는 데이터를 함수 호출이 끝난 후에도 그대로 유지해서 사용하는 기법
fun closureTest(): () -> String {
val data = "Data"
return { data }
}
fun main() {
val a = closureTest()
println(a())
}
// 결과
Data
'프로그래밍 > Kotlin' 카테고리의 다른 글
[Kotlin 요약 정리] 10. 함수형 프로그래밍과 람다 (0) | 2019.04.12 |
---|---|
[Kotlin 요약 정리] 9. 코틀린의 클래스 (0) | 2019.04.10 |
[Kotlin 요약 정리] 8. 추상 클래스와 인터페이스 (0) | 2019.04.10 |
[Kotlin 요약 정리] 7. 상속 (0) | 2019.04.09 |
[Kotlin 요약 정리] 6. 프로퍼티 (0) | 2019.04.09 |