함수 정의
기본 형식
fun add(x: Int, y: Int) : Int {
return x + y
}
단일 표현식 형식
fun add(x: Int, y: Int) : Int = x + y
복잡한 단일 표현식
fun compare(x: Int, y: Int) = if (x>y) x else y
println(compare(10, 20))
open class People {
fun hello() = println("Hello World")
}
fun compare2() = object : People() {} //익명 객체 반환
val p = compare2()
p.hello()
20 Hello World
인자 처리 규칙
위치인자
지정한 위치에 맞춰 인자를 지정
이름인자
매개변수 이름과 인자를 지정해서 처리
가변인자
인자의 개수가 미정일 때 사용
vararg 예약어를 사용
인자를 여러 개의 원소를 가지는 배열로 처리
fun add(x : Int, y: Int, z: Int) = x + y + z
addVar(10, 20, 30) //위치인자
addVar(z=30, x=10, y=20) //이름인자
addVar(10, y=30, z=30) //혼합
fun addVarArg(vararg x : Int): Int {
var result = 0
for (i in x) {
result += i
}
return result
}
println("가변인자 0 =" + addVarArg())
println("가변인자 4 =" + addVarArg(1,2,3,4))
println("가변인자 6 =" + addVarArg(1,2,3,4,5,6))
val ll = intArrayOf(1,2,3,4)
println("스프레드 연산 사용 =" + addVarArg(*ll))
가변인자 0=0 가변인자 4=10 가변인자 6=21 스프레드 연산 사용 =10
mutable/immutable 객체
immutable 객체
val ll = listOf(1,2,3,4)
println(ll)
fun addList(ll: List<Int>) : List<Int> {
val result = ll + listOf(6,7)
return result
}
val ll2 = addList(ll)
println(ll)
print(ll2)
[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4, 6, 7]
mutable 객체
val ml = mutableListOf(1,2,3,4)
println(ml)
fun addList(ml: MutableList<Int>) : MutableList<Int> {
ml.add(5)
return ml
}
val ml2 = addList(ml)
println(ml)
print(ml2)
[1, 2, 3, 4] [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
→ 따라서 mutable 객체를 인자로 전달할 때 함수 내부에서 영향을 미치지 않게 하기 위해선 인자를 복사하여 전달해야 한다.
익명함수
함수의 이름을 가지지 않으며 일회성으로 사용
이름을 가지지 않는다는 점 이외에 일반 함수와 다른 점은 없다
println((fun (arg1: Int, arg2: Int) : Int { // 즉시 실행
return arg1 + arg2
}) (100, 200))
val add = fun (arg1: Int, arg2: Int) : Int { // 변수에 할당
return arg1 + arg2
}
println(add(300, 200))
300 500
람다표현식
예약어와 함수 이름이 없다
매개변수와 표현식을 ->로 구분
기본적으로 return문을 사용할 수 없음(예외. 함수를 빠져나갈 때)
매개변수가 하나일 때 it 제공
{ println ( "No Argument" )}() // 인자가 없는 경우
println({ x: Int -> x * x }(10)) // 인자가 하나 있는 경우
fun func(x: Int, y: Int, f:(Int, Int) -> Int) : Int { // 함수를 인자로 가지는 경우
return f(x, y)
}
println(func(100, 200, {x,y -> x+y})) // 인자로 람다표현식 전달
No Argument 100 300
val ll = listOf(1,2,3)
println(ll.map { it * it }) // 매개변수가 하나일 때 사용
[1, 4, 9]
→ 람다표현식은 익명함수보다 더 축약된 표현
익명함수는 람다표현식보다 내부 코드가 많아질 때 사용
outer scope(상위 함수의 영역)의 변수를 접근할 수 있는 함수
익명함수나 람다식을 이용해 사용
일반 함수와의 차이점
fun outer(x: Int) {
fun inner(y: Int) = x + y
println(inner(x))
}
outer(10)
20
inner 내부에서 x 값을 사용할 수 있음
활용방법
함수를 값으로 취급하여 다른 함수의 인자나 반환값으로 사용하고 싶을 때
외부 변수의 값을 변경하거나 보존하고 싶을 때
콜백이나 리스너와 같은 비동기적인 작업을 처리하고 싶을 때
→ 클로저는 실행 시점에 생성되고 소멸되므로 비동기적인 작업에서도 outer scope에 접근 가능
렉시컬 스코핑
스코프 계층에서 변수를 검색하는 방법
처리 기준 : 내부 함수 → 외부 함수 → 전역