본 게시글은 부스트코스의 코틀린 기본프로그래밍을

시청한 후 학습한 정보를 기록하는 목적의 게시글입니다.

부스트코스

 

다 함께 배우고 성장하는 부스트코스

부스트코스(boostcourse)는 모두 함께 배우고 성장하는 비영리 SW 온라인 플랫폼입니다.

www.boostcourse.org

코틀린 기본프로그래밍(1/2)

 

코틀린 프로그래밍 기본1/2(함수편)

부스트코스 무료 강의

www.boostcourse.org

본 게시글은 부스트코스 서포터즈 3기 활동 게시글입니다.


#4-1. 이름없는 함수의 또 다른 형태, 람다(Lambda)!

- 들어가기 전에

람다식에 대한 선언 방법을 좀 더 자세히 알아볼까요? 변수에 할당해 이름 있는 함수처럼 있습니다! 시작해 봅시다.

 

- 핵심 키워드

  • 람다 함수 혹은 람다식
  • 람다식의 축약식 표현법
  • 화살표 표현법
  • 반환 자료형이 없을때 Unit

 

1) 람다식을 변수에 넣어보기

fun main() {

    var result: Int
    
    val multi = {x: Int, y: Int -> x * y}
    
    result = multi(10, 20)
    println(result)   
}

 

일반 변수에 람다식을 할당할 수 있으며,

람다식이 할다된 변수는 함수처럼 사용할 수 있다.

 

아래와 같이 표현식이 2줄 이상일 때는 마지막 표현식이 반환된다.

val multi2: (Int, Int) -> Imt = { x:Int, y:Int ->
    println("x * y")
    x * y // 마지막 표현식
}

또한 람다식은 자료형을 생략하여 표현할 수 있다.

따라서 아래의 세 줄은 모두 같은 동작을 수행한다.

val multi:(Int, Int) -> Int = {x: Int, y: Int -> x * y}
val multi = {x: Int, y: Int -> x * y}
val multi:(Int, Int) -> Int = {x, y -> x * y}

 

2) 변환 자료형이 없는 표현

반환 자료형이 없을 경우에는 람다 표현식에 Unit을 사용할 수 있다.

val greet : ()->Unit = { println("Hello World!") }

인자가 없는 경우에도 위와같이 소괄호의 부분을 비워놓을 수 있다.

우항에서 화살표 기호가 없는 것을 확인할 수 있다.

 

3) 람다식 안에 라다식

람다식 역시 함수이기에 람다식 안에 람다식이 존재할 수 있다.

val nestedLambda : () -> () -> Unit = {{ println("nested") }}

 

4) 자료형 생략

자료형이 추론가능할 경우에 자료형을 생략할 수 있다.

val greet = { println("Hello World!") } // 추론 가능
val square = { x : Int -> x * x } // 선언 부분을 생략하려면 x의 자료형을 명시하여야 함
val nestedLamda = {{ println("nested") }} // 추론 가능

 

#4-2. 고차함수와 람다식의 이해 (1)

- 들어가기 전에

고차 함수는 인자나 반환값으로 함수를 사용합니다. 이때 함수는 일반적으로 이름이 있는 함수일 수도 있고 이름이 없는 함수일 수도 있습니다. 다양한 함수 형태를 통해 람다식을 호출 원리를 더 깊이 이해해 봅시다.

 

- 핵심 키워드

  • 고차 함수
  • 함수의 인자나 반환값으로 함수 사용하기
  • 값의 의한 호출
  • 이름에 의한 호출
  • 참조에 의한 호출

 

1) 함수의 인자로 함수 사용해보기

fun sum(a: Int, b: Int) = a + b

fun mul(a: Int, b: Int): Int{
    return a * b
}

fun main(){
    val result1 = sum(a: 10, b: 10);
    val result2 = mul(sum(a: 10, b: 5), b: 10)
    
    println($result1, $result2)
}

 

2) 함수의 반환값으로 함수 사용하기

fun sum(a: Int, b: Int) = a + b

fun funcFunc(a: Int, b: Int) = sum(a, b)

fun main(){
    val result3 = funcFunc(a: 2, b: 3)
    
    println($result3)
}

 

3) 고차함수 - 람다식 함수를 매개변수와 인자로 사용하기

fun main() {
    var result: Int

    // 람다식을 매개변수와 인자로 사용한 함수
    result = highOrder({x, y -> x + y}, 10, 20)
    println(result)
}

fun highOrder(sum: (Int, Int) -> Int, a: Int, b: Int): Int {
    return sum(a,b)
}

https://www.boostcourse.org/mo132/lecture/59976

 

4) 값에 의한 호출 방법 - 단순 람다식 함수의 인자 전달

!. 함수가 인자로 전달될 경우

람다식 함수는 값으로 처리되며 그 즉시 함수가 수행된 후 값을 전달

fun main() {
    val result = callByValue(lambda())  // 람다식 함수를 호출
    println(result)
}

fun callByValue(b: Boolean): Boolean {  // 일반 변수 자료형으로 선언된 매개변수
    println("callByValue function")
    return b
}

val lambda: () -> Boolean = {  // 람다 표현식이 두 줄이다
    println("lambda function")
    true  // 마지막 표현식 문장의 결과가 반환
}

https://www.boostcourse.org/mo132/lecture/59976

 

5) 이름에 의한 호출 - 람다식 선언 및 이름의 호출

!. 함수가 이름으로 호출된 경우

람다식 내용물이 결과가 아니라 통째로 할당된다.

fun main() {
    val result = callByName(otherLambda)  // 람다식 이름으로 호출
    println(result)
}

fun callByName(b: () -> Boolean): Boolean {  // 람다식 함수 자료형으로 선언된 매개변수
    println("callByName function")
    return b()
}

val otherLambda: () -> Boolean = {
    println("otherLambda function")
    true
}

https://www.boostcourse.org/mo132/lecture/59976

 

6) 다른 함수의 참조에 의한 호출

!. 함수가 참조에 의해 호출된 경우

일반함수의 내용물이 람다식에 존재하는 매개변수와 반환 값에 완벽히 일치하는 경우

참조로 호출할 수 있으며, 참조로 호출한 경우

내부적으로 람다식에 매치해서 내용물에 가져오게 된다.

단, 참조로 호출할 경우 콜론 두개를 함수 이름 앞에 선언하여야 한다.

fun sum(x: Int, y: Int) = x + y

funcParam(3, 2, sum)  // 오류! sum은 람다식이 아님

...

fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int {
	return c(a, b)
}

funcParam(3, 2, ::sum)

 

#4-2. 고차함수와 람다식의 이해 (2)

- 들어가기 전에

람다식에 대한 선언 방법을 좀 더 자세히 알아볼까요? 변수에 할당해 이름 있는 함수처럼 있습니다! 시작해 봅시다.

 

- 핵심 키워드

  • 람다 함수 혹은 람다식
  • 람다식의 축약식 표현법
  • 화살표 표현법
  • 반환 자료형이 없을때 Unit

 

1) 람다식 함수의 매개변수 - 매개변수가 없는 경우

fun main() {
    // 매개변수 없는 람다식 함수
    noParam({ "Hello World!" })
    noParam {"Hello World!"}  // 위와 동일 결과, 소괄호 생략 가능
}

// 매개변수가 없는 람다식 함수가 noParam 함수의 매개변수 out으로 지정됨
fun noParam (out: () -> String) = println(out())

 

2) 람다식 함수의 매개변수 - 매개변수가 한개인 경우

매개변수가 한 개인 경우는 이를 it으로 대체할 수 있다.

fun main() {
    // 매개변수 없는 람다식 함수
...
    // 매개변수가 하나 있는 람다식 함수
    oneParam({ a -> "Hello World! $a" })
    oneParam { a -> "Hello World! $a" } // 위와 동일 결과, 소괄호 생략 가능
    oneParam { "Hello World! $it" }  // 위와 동일 결과, it으로 대체 가능
}
...
// 매개변수가 하나 있는 람다식 함수가 oneParam함수의 매개변수 out으로 지정됨
fun oneParam(out: (String) -> String) {
    println(out("OneParam"))
}

 

3) 람다식 함수의 매개변수 - 매개변수가 두 개 이상인 경우

fun main() {
...
    // 매개변수가 두 개 있는 람다식 함수
    moreParam { a, b -> "Hello World! $a $b"} // 매개변수명 생략 불가
...
}
// 매개변수가 두 개 있는 람다식 함수가 moreParam 함수의 매개변수로 지정됨
fun moreParam(out: (String, String) -> String) {
    println(out("OneParam", "TwoParam"))
}

 

4) 람다식 함수의 매개변수 - 매개변수를 생략하는 경우

moreParam { _, b -> "Hello World! $b" }  // 첫 번째 문자열은 사용하지 않고 생략

 

5) 일반 매개변수와 매개변수의 사용

...
fun main(){
...
    //인자와 함께 사용하는 경우
    withArgs("Arg1", "Arg2", {a, b -> "Hello World! $a $b }) // case #1
    //withArgs()의 마지막 인자가 람다식인 경우 소괄호 바깥으로 분리 할 수 있다.
    withArgs("Arg1", "Arg2") {a, b -> "Hello World! $a $b }) // case #2
}
...
//withArgs 함수는 일반 매개변수를 2개를 포함, 람다식 함수를 마지막 매개변수로 가진다.
fun withArgs(a: String, b: String, out : (String, String) -> String){
    println(out(a, b))
}

 

6) 두 개의 람다식 매개변수를 가진 함수

fun main() {
    twoLambda({a, b -> "First $a $b"}, {"Second $it"})
    twoLambda({a, b -> "First $a $b"}) {"Second $it"}  // 위와 동일
}

fun twoLambda(first: (String, String) -> String, second: (String) -> String) {
    println(first("OneParam", "TwoParam"))
    println(second("OneParam"))
}
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기