스칼라에서 익명 함수(Anonymous Function)는 다음과 같은 형태로 정의합니다.

// 이 함수의 타입은 하나의 Int형 매개변수를 받아 Int형으로 그 제곱을 리턴하는 Int => Int입니다.
(x: Int) => x * x
// 이 함수의 타입은 두 개의 Int형 매개변수를 받아 그 합을 Int를 리턴하는 (Int, Int) => Int입니다.
(x: Int, y: Int) => x + y

익명 함수는 타입을 가지는데요. 예를 들어 다음 코드의 doWithOneAndTwo를 보면 (Int, Int) => (Int)와 같은 타입의 익명 함수만 받아들입니다.
따라서 코드 13번째 줄과 같이 (x, y) => x + y와 같은 익명 함수를 매개변수로 사용할 수 있습니다.
여기서 x와 y의 타입을 지정하지 않고 생략했는데요. 컴파일러가 코드 4번째 줄을 보고 타입을 알 수 있기 때문입니다.

추가로 더 짧게 변수명을 생략할 수도 있습니다. x와 y가 익명 함수의 Body에서 딱 한 번만 사용된다면 _로 대체할 수 있는데요. 익명 함수의 Body에 나타나는 _의 순서는 매개변수에 정의된 순서대로 입니다.
예를 들어 _ / _는 x/y와 같습니다.

하지만 만약 y/x처럼 순서를 바꿔서 표현하고 싶으면 까다로워지는데요. (1/_)*_라고 표현해야겠지요. (1/x)*y는 y/x이니까요.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
object LearnScala {
    
    // 매개변수로 받은 익명함수에 1과 2를 넣어서 실행하는 메소드
    def doWithOneAndTwo(f: (Int, Int) => Int) = {  
        f(12//return은 생략되었지만, f(1, 2)의 결과가 return
    }
    
    def main(args: Array[String]): Unit = {
        // ① 명시적으로 타입을 선언하는 익명함수
        val call1 = doWithOneAndTwo((x: Int, y: Int) => x + y)
        
        // ② 코드4번째 줄에서 익명함수의 매개변수 타입(Int, Int)을 이미 정했기 때문에 생략
        val call2 = doWithOneAndTwo((xy=> x + y)  
        
        // ③ 이렇게 요약할 수도 있음
        val call3 = doWithOneAndTwo(_ + _) // 매개변수의 순서대로 _에 대입됨
        
        val call4 = doWithOneAndTwo((x:Int, y:Int)=> x*y)
        val call5 = doWithOneAndTwo((x,y)=>x-y)
        val call6 = doWithOneAndTwo(_ % _)
        
        println(call1, call2, call3, call4, call5, call6)
    }
}
cs


출력 (3,3,3,2,-1,1)


스칼라에서 메소드는 다양한 형태로 정의할 수 있습니다.
우선 리턴 값이 있는 메소드는 메소드를 정의하는 블록 { }전에 =을 적어주어야 합니다.
그리고 리턴 키워드는 옵션입니다. 적어주지 않으면 리턴 타입은 리턴 값에 의해 결정됩니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
object LearnScala {
    // ① 일반적인 메소드
    def add(x:Int, y:Int):Int = {
        return x + y        
    }
    
    // ② return을 생략한 메소드
    def addWithoutReturn(x:Int, y:Int) = { // x + y는 int이므로 return타입은 Int로 결정됩니다.
        x + y // return을 적어주지 않아도 마지막 값이 return값입니다.
    }
    
    // ③ 메소드가 한 줄일 경우 중괄호{}를 생략해도 됩니다.
    def addWithoutBlock(x:Int, y:Int) = x + y
    
    def abs(x:Int) = x.abs
    def Max(x:Int, y:Int):Int = {
        x.max(y)
    }
    def main(args: Array[String]): Unit = {
        println(s"① ${add(1,2)}")
        println(s"② ${addWithoutReturn(1,2)}")
        println(s"③ ${addWithoutBlock(1,2)}")      
        println(s"④ ${abs(-3)}")
        println(s"⑤ ${Max(-1,5)}")
    }
}
cs


출력 ① 3
② 3
③ 3
④ 3
⑤ 5


+ Recent posts