kotlin

코틀린 : 함수형 프로그래밍

ChloeLee 2020. 10. 20. 20:34

함수가 일급 객체

함수도 하나의 사용자 정의 자료형

함수를 이용해서 변수를 생성할 수도 있고 함수 안에 변수, 함수, 클래스를 생성하는 것이 가능

 

 

 

Pure Function 사용을 권장 : 외부의 영향을 받지 않아야 한다

동일한 입력에 대해서 동일한 결과 생성
매개 변수가 있어야하고 리턴 되는 데이터가 있어야 한다.

 

데이터의 불변성

함수의 매개변수는 읽기 전용

함수의 결과를 리턴할 때는 새로운 데이터를 만들어서 리턴

 

장점

동시성 작업을 조금 더 쉽고 안전하게 구현

 

일급 객체란?

//Kotlin에서는 함수가 일급객체
// 변수로 만들 수도 있고 함수 안에 함수나 클래스를 생성하는 것 가능
fun method(){
    // 함수 안에서 함수 생성 가능
    fun subFun(){
        println("내부 함수")
    }
    //클래스 생성 가능
    class SubClass{
    }
}
// 2개의 실수를 받아서 더한 후 실수를 리턴하는 함수
fun addDoubleFun(d1 : Double, d2 : Double) : Double {
    return d1 + d2
}

//람다 표현식으로 만들고 변수에 대입
var addDoubleLambda = {x1:Double, x2:Double -> x1 + x2}

// 원형으로 표현 : {Double, Double -> Double}

fun main(args:Array<String>){
    //method1 이라고 하는 최상위 레벨의 top level method1을
    //f 에 대입
    var f = ::method1
    // method1을 수행한 것과 동일한 효과
    f()

    println(addDoubleFun(10.8, 20.7))
    println(addDoubleLambda(30.8, 20.9))
}

 

람다 표현식, 익명함수, closure

익명함수 : 함수의 이름이 없는 것

람다 표현식 : 익명 함수이고 표기법이 일반 함수와는 조금 다름

Closure : 함수 안에 함수를 만들어서 함수 내부의 데이터를 함수 외부에서 변경하도록 하는 것

             > 내부 함수를 리턴

 

1) 람다 표현식

함수 표현식을 간결하게 만든 표현식

함수 표현 방법 -> fun 함수이름 (매개변수 나열): 리턴 타입 {함수 내용}

람다 표현식 -> {매개 변수 나열 -> 함수 내용}

 

2) 규칙

람다는 반드시 {} 안에 작성 합니다.

-> 를 기준으로 왼쪽은 매개 변수이고 오른쪽은 함수의 내용

 

매개변수의 자료형은 기재를 해야하는데 추론이 가능하면 생략하는 것도 가능

val v = 10 // 바로 데이터가 대입 되면 데이터를 가지고 자료형을 추론할 수 있다

리턴 타입을 기재하지 않는데 함수의 내용의 마지막 표현식의 결과가 리턴되는 값이다.

 

매개 변수가 없을 때는 함수 내용만 작성해도 된다.

 

3) 사용

고차 함수 (함수를 매개 변수로 받거나 함수를 리턴하는 함수)의 매개변수로 대입 하거나 리턴 할 때 주로 이용

 

4) 최근에는 이벤트 처리를 할 때 화면에 보여지는 code sense가 람다 형태로 제공 되는 경우가 많습니다.

 

5) 람다 표현식을 만들고 바로 호출

변수에 저장하고 함수 처럼 호출

람다 표현식 뒤에 매개 변수 대입

run() 안에 작성해서 호출

람다는 안드로이드에서는 대부분 매개 변수로 대입하기 때문에 직접 호출할 가능성이 거의 없다

 

6) 함수나 람다의 타입 표현 방법

(매개변수의 자료형 나열) -> 리턴 타입

 

7) 람다에서 매개변수가 1개인 경우는 매개 변수의 선언을 생략하고 it라는 이름으로 내용에서 사용 가능

fun oneArg(n:Int) -> Int{

    return n*100

}

=> 위 함수의 자료형은 (int) -> Int 

 

{x:Int -> x * 100}

 

매개 변수가 1 개 라서 생략하고 it 를 이용 가능

{it * 100}

 

위의 문법을 이용하면 데이터 변환이 편리

class User (val num:Int, val name: String, val score:Int){}

User 클래스는 num, name, score 라는 프로퍼티로 구성

 

User 클래스의 인스턴스의 score 만 필요한 경우

(User) -> Int = {it.num} // 이 람다는 User 객체를 대입하면 Score 값을 리턴합니다.

 

특정 프로퍼티의 값을 리턴 할 때는 클래스 이름 :: 프로퍼티 이름만 리턴해도 됩니다.

(User) -> Int = User::num 도 위와 동일한 효과를 나타냅니다.

 

High Order Function : 고차함수

함수를 매개변수로 사용하거나 리턴하는 함수

이런 경우는 Android의 Event Processing 이나 Collection Data의 Map-Reduce Programming에 많이 사용

매개 변수가 1 개인 함수에서 매개 변수가 함수라면 함수를 호출 할 때 ()를 하지 않고
{람다 표현식} 형태로 람다 표현식만 작성하는 것이 가능합니다.

매개 변수가 여러 개이고 함수가 가장 마지막 매개 변수일 때
마지막 매개 변수는 () 안에 기재 하지 않고 외부에 {람다 표현식}으로 기재 해도 됩니다.

 

함수(매개 변수 함수)

함수({람다 표현식}) => 함수(){람다 표현식}

 

Button 의 ClickEvent 처리는 View 클래스의 내부 인터페이스인 OnClickListener의 onClick 함수가 처리합니다.

 

class EvnetHandler : View.OnClickListener{

    onClick(sender:View){

        내용

    }

}

 

버튼.setOnClickListener(EventHandler())

 

버튼.setOnClickListener(View.OnClickListener(){

    onClick(sender:View){

        내용

    }})

}

 

버튼.setOnClickListener({sender -> 내용})

 

버튼.setOnClickListener{sender -> 내용}

 

메소드가 1 개인 인터페이스 구현 -> 람다 표현식 -> () 바깥에 사용하는 람다 표현식