Kotlin - 함수 & Lambda Expression
함수의 형식
기본 형식
fun 함수이름(형식 인자 이름 : 인자 타입(Int..)): 반환 타입(Int..) {
// Method Body
return _
}
// 반환값이 없는 경우 -> 반환 타입에 Unit (생략 가능)
fun carefreeLife(length: Int, breadth: Int): Unit {
print(length * breadth)
}
예시
fun add(a: Int, b: Int): Int { // formal parameters
return a + b
}
fun main() { // Top-level Function
val res = Function().add(3, 5) // Actual arguments
print(res)
}
간단한 함수인 경우 - 수식처럼 사용 가능
// 아래와 같이 함수의 Return 값을 직접 할당 할 수 있다.
// 마치 함수가 변수인 것처럼 사용 가능.
fun add(a: Int, b: Int) = a + b
fun max(a: Int, b: Int) = if(a > b) a else b
- 간단한 로직을 가진 함수인 경우
- 함수의 반환 타입 생략 가능 (두 개의 형식 인자가 같은 Type을 가졌으므로)
- 함수의 반환 값을 중괄호 및 Return 문 사용 없이 설정 가능.
Named Parameters
// function.kt
fun findVolume(length: Int, width: Int, height: Int = 10) = length * width * height
// main.kt
import function.Function
fun main() { // Top-level Function
println(Function().findVolume(2,3))
println(Function().findVolume(2,3, 30)) // 실 매개변수 (Actual Parameter)
print(Function().findVolume(width = 20, length = 10)) // 실 매개변수의 순서를 바꿔 함수 사용
print(Function().findVolume(height = 30, length = 10, width = 10))
}
- 함수에 지정된 매개 변수의 입력 순서를 Custom 하여 사용 할 수 있다.
- 해당 함수에 실 매개 변수 입력 시 매개 변수의 이름을 지정하여 입력.
- 매개 변수의 Default 값 지정 가능.
- 함수 호출 시 Default 로 지정된 Parameter 를 생략하게 되면 Default 값이 자동 삽입됨.
Functions with Various Arguments
// function.kt
// 가변 인자 : 인자의 개수가 변할 수 있다.
// 여러 개의 인자가 입력될 수 있으므로 배열로서 구현됨.
fun addWithVararg(vararg values: Int): Int {
var sum = 0
for (e in values) {
sum += e
}
return sum
}
// main.kt
fun main() { // Top-level Function
println(function.Function().addWithVararg(1, 2, 3, 4))
println(function.Function().addWithVararg(1, 2, 3, 4, 5, 6, 7))
}
Lambda 식과 고차 함수
함수형 프로그래밍 (Functional Programming)
// Lambda 식 예시
val add = {x: Int, y: Int -> x + y}
모든 코드를 순수 함수로 작성하여 프로그램의 부작용 (side effect) 을 해결하려는 프로그래밍 기법
- 순수 함수 (Pure Function)
- 같은 Parameter 에 대하여 항상 같은 값을 반환.
- 함수 바깥의 어떤 상태도 바꾸지 않음.
- 일급 함수 (First Class Citizen)
- 람다 식 (Lambda Expression) 은 일급 함수
- 일급 객체는 함수의 parameter 로 전달할 수 있다. (Actual Argument)
- 일급 객체는 함수의 Return 값에 사용할 수 있다.
- 일급 객체는 변수에 저장 할 수 있다.
- 고차 함수 (High Order Function)
- 다른 함수를 Parameter 로 사용하거나 함수를 Return 값으로 반환
람다 식 (Lambda Expression)
// 변수 변수 타입 람다식{람다 식의 형식인자 -> 람다 식의 본문}
val add: (Int, Int) -> Int = {x: Int, y: Int -> x + y}
println(add(1, 2))
// 람다 식의 형식인자에 Type이 선언되어 있으므로 변수 타입, 리턴 타입 생략 가능
val add2 = {x: Int, y: Int -> x + y}
// 변수 타입, 리턴 타입이 선언되어 있으므로 람다 식(형식 인자)의 타입 생략 가능.
val add3: (Int, Int) -> Int = {x, y -> x + y}
- 람다 식 : Function with no name
- 변수에 람다 식을 할당
- 구성:
- **
val (변수): (변수 타입) -> (리턴 타입) = {람다 식의 형식인자 -> 람다 식 본문**}
- **
(Lambda) 변수에 함수 저장
// 일반적인 표현
fun main() { // Top-level Function
// 함수를 값으로 참조할 때 함수 참조 연산자(::) 를 사용.
val addFunction = ::add
addFunction()
}
fun add() {
println("General Function")
}
// Lambda 식 표현
fun main() { // Top-level Function
val addFunction = add
// 같은 동작을 실행
addFunction()
add()
}
// 함수가 아닌 변수로서 직접 할당
//
val add: () -> Unit = {
println("Lambda Expression")
}
(Lambda) 함수를 Data Type 으로 사용
// Lambda 식 표현
fun main() { // Top-level Function
val addFunction = add
// 같은 동작을 실행
addFunction()
add()
val subFunction = sub
subFunction()
sub()
}
val add = {
println("Lambda Expression")
}
// Parameter 없음: () -> 반환 타입 없음: Unit
val sub: () -> Unit = {
println("Subtract Operation")
}
(Lambda) 함수를 Return Type 으로 사용
// function2_lambda
val add: () -> Unit = {
println("Add Operation")
}
val sub: () -> Unit = {
println("Subtract Operation")
}
fun addOrSubtract(flag: Boolean): () -> Unit {
if (flag) {
return add
} else {
return sub
}
}
// main.kt
fun main() {
val addFunction = function2_Lamda().addOrSubtract(true)
val subFunction = function2_Lamda().addOrSubtract(false)
addFunction()
subFunction()
}
(Lambda) 함수를 다른 함수의 인자로 전달
// function2_lambda()
val add: () -> Unit = { println("Add Operation") }
val sub: () -> Unit = { println("Subtract Operation") }
// 3. Parameter 로 전달된 Lambda 식을 함수 내부에서 사용.
fun addOrSubtract(flag: Boolean, x:Int, y:Int, op:(Int, Int) -> String) {
if (flag) {
add()
println(op(x, y))
}
else {
sub()
println(op(x, y))
}
}
// main.kt
import function.function2_Lamda
fun main() {
// 1. Lambda 함수를 변수로서 생성
val addOp: (Int, Int) -> String = {a, b ->
"$a + $b = ${a + b}"
}
val subOp: (Int, Int) -> String = {a, b ->
"$a - $b = ${a - b}"
}
// 2. 변수가 된 Lambda 식을 다른 함수의 인자로서 전달
function2_Lamda().addOrSubtract(true, 2, 3, addOp)
function2_Lamda().addOrSubtract(false, 6, 4, subOp)
}
- 위와 같이 Lamda 함수로서 변수를 생성하고 해당 Lambda 식을 변수로서 함수의 인자로 전달하여 사용 할 수 있다.
익명 함수 (Anonymous Functions)
Anonymous Function 역시 이름이 없는 함수이다. - Lambda Expression 과 비슷하지만 익명 함수는 일반 함수이기 때문에 제어 문장 (return, break, continue) 을 사용할 수 있다.
fun main() {
// fun(a, b) = a + b "익명 함수"
val add: (Int, Int) -> Int = fun(a:Int, b:Int): Int = a + b
// Lambda Expression
val add2 = {a: Int, b: Int -> a + b}
println(add(10, 2))
println(add2(10, 2))
}
Inline Functions
Inline Functions : 코드를 복사하여 함수를 구현 - Inline Function을 호출하는 곳에 함수 본문 내용을 그대로 복사. - 메모리 사용량 증가 - Lambda Expression 과 같은 형태의 매개변수 사용 - 일반 함수보다 빨리 처리되기 때문에 성능 향상 - Inline Function 은 Stack과 같은 과정을 거치지 않음. - Inline Function 내부 코드는 짧아야 하며, 잦은 사용은 지양 할 것.
fun main() {
println(add(2,3))
println(add(5,7))
}
inline fun add(a: Int, b: Int): Int = a + b
확장 함수 (Extension Functions)
확장 함수: Class 에 새로운 함수를 추가 하는 것. - Class 내부에 필요로 하는 함수를 선언하지 않고 추가 할 수 있다. - 추가된 확장 함수는 static 으로 동작하게 됨. - 개발자가 만든 Class 및 Kotlin 자체에 존재하는 기존 클래스 (String, Int, Array … etc) 에 필요로 하는 기능을 추가. - 코드의 길이 감소 및 가독성 증가의 효과.
사용자 정의 Class 에 확장 함수 추가하기
class Student {
fun hasPassed(score: Int): Boolean {
return score > 60
}
// 직접 클래스 내부에 선언하지 않고 확장 함수로 추가 가능
// fun isScholar(score: Int): Boolean {
// return score > 90 // }
}
// 확장 함수 추가
// fun (추가할 클래스).(확장 함수 이름) { 확장 함수 코드 }
fun Student.isScholar(score: Int): Boolean {
return score > 90
}
fun main() {
// Create an Instance of the Class Student
val Chae = Student()
println("Pass status: ${Chae.hasPassed(88)}")
// Extension function 사용
println("Scholarship status: ${Chae.isScholar(95)}")
}
Predefined Class 에 확장 함수 추가하기
// Predefined Class 인 "String" Class 에 "add" 확장 함수 추가.
fun String.add(s1: String): String {
// this : add 메소드를 호출한 객체인 "String" 을 나타냄.
return this + s1
}
fun extensionFunc() {
val s: String = "Hello, "
val s1: String = "Kotlin!"
println(s.add(s1))
}
지식 공유 및 기록을 위한 Kotlin 개인 학습 포스트입니다. 피드백은 항상 환영합니다! 긴 글 읽어주셔서 감사합니다.
Task Lists
- 함수의 형식
- 기본 형식
- 간단한 함수인 경우 - 수식처럼 사용 가능
- Named Parameters
- Functions with Various Arguments
- Lambda 식과 고차 함수
- 함수형 프로그래밍 (Functional Programming)
- 람다 식 (Lambda Expression)
- 익명 함수 (Anonymous Functions)
- Inline Functions
- 확장 함수 (Extension Functions)
Comments