티스토리 뷰
일급 시민(First-class citizen)
1. 일급 시민
• 다음 조건을 만족하는 것을 말한다.
- 1. 변수나 자료 구조에 저장할 수 있다.
- 2. 함수의 매개 변수에 전달할 수 있다.
- 3. 함수의 반환 값으로 사용할 수 있다.
• 즉, 자유롭게 변수 안으로 들어가고, 값처럼 사용되고 하는 것.
2. 일급 객체
• 일급 시민인 객체
3. 일급 함수
• 일급 객체인 함수
• 사람에 따라 다음 조건을 추가로 붙이기도 한다.
- 4. 익명으로 생성할 수 있다.
- 5. 런타임에 생성할 수 있다.
• 코틀린에서 함수는 일급 함수이다.
고차 함수(High-order function)
• 함수를 파라미터로 받는 함수. 또는, 함수를 리턴하는 함수
• 즉, 함수 안에 함수가 들어가는 형태
• 고차 함수를 지원하는 언어가 있고, 지원하지 않는 언어가 있다.
- 그 언어에서 함수가 일급 함수냐 아니냐에 따라 갈린다.
• 코틀린에서의 함수는 일급 함수이므로 고차 함수를 지원한다.
• 고차 함수 자료형 표시 방법
- (자료형) -> 자료형
ex) (Int, Int) -> String
- Int형 2개를 받아 String형을 리턴
• 고차 함수 호출 방법
- 함수 안에서 함수를 사용할 때, 즉 인자로 넣거나 리턴할 때는 함수라는 것을 알려주기 위한 ::를 붙여야 한다.
ex) 인자로 받을 때 : funcName(::funcName2)
ex) 리턴할 때 : return ::funcName2
// 매개 변수에 들어오는 함수
fun sum(num1: Int, num2: Int): Int {
return num1 + num2
}
fun sub(num1: Int, num2: Int): Int {
return num1 - num2
}
fun calculator(num1: Int, num2: Int, f: (Int, Int) -> Int): Int { // 'Int 2개를 받고 Int를 리턴하는 함수 f'를 인자로 받는 calculator 함수.
val RESULT = f(num1, num2) // 함수 f에 num1, num2를 넣어 실행한다.
return RESULT
}
println(calculator(200, 100, ::sum)) // 300 출력 : 함수 f에 sum 함수를 넘겨주었기 때문에 덧셈 실행.
println(calculator(200, 100, ::sub)) // 100 출력 : 함수 f에 sub 함수를 넘겨주었기 때문에 뺄셈 실행.
// 리턴되어 나가는 함수
fun calculator2(str: String): (Int, Int) -> Int { // 'Int 2개를 받고 Int를 리턴하는 함수'를 리턴하는 calculator2 함수.
if (str == "덧셈기") {
return ::sum // sum 함수 리턴
} else {
return ::sub // sub 함수 리턴
}
}
val sum2 = calculator2("덧셈기") // 리턴한 sum 함수를 sum2 변수에 넣는다.
val sub2 = calculator2("뺄셈기") // 리턴한 sub 함수를 sub2 변수에 넣는다.
println(sum2(50, 50)) // 100 출력 : sum2 변수에 함수가 들어갔기 때문에 함수로 작동
println(sub2(50, 50)) // 0 출력 : sub2 변수에 함수가 들어갔기 때문에 함수로 작동
람다식(Lambda)
• 함수를 하나의 식으로 표현한 것.
• 고차 함수를 사용할 때 유용하다.
- 함수를 변수에 넣어, 다시 그 변수를 사용하는 번거로운 작업을 하는 대신, 변수를 거치지 않고 한 번에 함수를 적을 때 사용.
- 변수도, 함수 이름도 필요없으므로 익명 함수의 한 종류이다.
• 람다 함수에서는 return 키워드를 사용할 수 없고, 마지막 줄이 자동 리턴된다.
fun calculator(num1: Int, num2: Int, f: (Int, Int) -> Int): Int {
return f(num1, num2)
}
// 1. 정석
val lambdaSum: (Int, Int) -> Int = { num1: Int, num2: Int -> num1 + num2 }
println(lambdaSum(1, 2)) // 3 출력
println(calculator(3, 4, lambdaSum)) // 7 출력 : 람다 함수는 ::를 붙일 필요가 없다.
// 2. 생략
// 2.1. 생략1 : 오른쪽 타입 생략
val lambdaSum2: (Int, Int) -> Int = { num1, num2 -> num1 + num2 }
println(lambdaSum2(5, 6)) // 11 출력
println(calculator(7, 8, lambdaSum2)) // 15 출력
// 2.2. 생략2 : 왼쪽 타입 생략
val lambdaSum3 = { num1: Int, num2: Int -> num1 + num2 }
println(lambdaSum3(9, 10)) // 19 출력
println(calculator(11, 12, lambdaSum2)) // 23 출력
// 2.3. 생략3 : 고차 함수에 익명 함수로 바로 사용할 경우 타입이 외부에 명시되어 있으면 생략 가능
println(calculator(13, 14, { num1, num2 -> num1 + num2 })) // 27 출력
// 3. 파라미터가 없는 람다 함수
val lambda31: () -> Int = {
15 + 16
}
println(lambda31()) // 31
// 4. 파라미터가 한 개인 경우에는 it을 사용한다.
val lambdaSum18: (Int) -> Int = {
it + 18
}
println(lambdaSum18(17)) // 35
이 글은
패스트 캠퍼스 Android 앱 개발의 정석 with Kotlin 올인원 패키지 Online
강의를 듣고 공부한 내용을 바탕으로 작성되었습니다.
'📱 Android > 💻 Kotlin' 카테고리의 다른 글
[Android/Kotlin] 15. 클래스 2편 (2) | 2022.10.12 |
---|---|
[Android/Kotlin] 14. 클래스(Class) (1) | 2022.10.11 |
[Android/Kotlin] 12. 출력 (0) | 2022.10.07 |
[Android/Kotlin] 11. 예외 처리 (0) | 2022.10.07 |
[Android/Kotlin] 10. 반복문 (0) | 2022.10.06 |