Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행하고 있다.


9장

코드 중복 줄이기

  • 고차 함수 : 함수를 인자로 받는 함수
object FileMatcher {
    private def filesHere = (new java.io.File(".)).listFiles
    def fileEnding(query: String) =
        for (file <- filesHere; if file.getName.endsWith(query))
            yield file
    def fileContaining(query: String) =
        for (file <- filesHere; if file.getName.contains(query))
            yield file
    def fileRegex(query: String) =
        for (file <- filesHere; if file.getName.matches(query))
            yield file
    
}
  1. 함수값 사용
// 중복 코드를 함수로 작성
def filesMatching(query: String, matcher: (String, String) => Boolean) = {
    for (file <- filesHere; if matcher(file.getName, query))
        yield file
}

def fileEnding(query: String) =
    filesMatching(query, _.endsWith(_)) // 함수값
def fileContaining(query: String) =
    filesMatching(query, _.contains(_)) // 함수값
def fileRegex(query: String) =
    filesMatching(query, _.matches(_)) // 함수값
  1. 클로저 사용
// 클로저 사용하여 인자 제거
private def filesMatching(matcher: (String, String) => Boolean) = {
    for (file <- filesHere; if matcher(file.getName))
        yield file
}

def fileEnding(query: String) =
    filesMatching(_.endsWith(query))
def fileContaining(query: String) =
    filesMatching(_.contains(query))
def fileRegex(query: String) =
    filesMatching(_.matches(query))

클라이언트 코드 단순하게 만들기

def containsNeg(nums: List[Int]): Boolean = {
    var exists = false
    for (num <- nums)
        if (num < 0)
            exists = true
    exists
}

def containsNeg(nums: List[Int]) = nums.exists(_ < 0)
def containsOdd(nums: List[Int]): Boolean = {
    var exists = false
    for (num <- nums)
        if (num % 2 == 1)
            exists = true
    exists
}

def containsOdd(nums: List[Int]) = nums.exists(_ % 2 == 1)

커링

  • 커링 : n개의 인자를 받는 함수를 n개의 함수로 각각의 인자를 받도록 하는 것
def plainOldSum(x: Int, y: Int) = x + y
plainOldSum(1, 2)

def curriedSum(x: Int)(y: Int) = x + y  // 커링
curriedSum(1)(2)

val onePlus = curriedSum(1)_    // 인자 하나 받아서 1을 더하는 함수
onePlus(2)

새로운 제어구조 작성 - 중괄호

인자를 1개 전달하는 경우에 함수 인자를 감싸는 소괄호 대신 중괄호 사용 가능

def withPrintWriter(file: File, op: PrintWriter => Unit) {
    val writer = new PrintWriter(file)
    try {
        op(writer)
    } finally {
        writer.close()
    }
}

withWriter(
    new File("date.txt"),
    writer => writer.println(new java.util.Date)
) // 빌려주기 패턴. 자원 닫기가 보장됨
def withPrintWriter(file: File)(op: PrintWriter => Unit) {
    val writer = new PrintWriter(file)
    try {
        op(writer)
    } finally {
        writer.close()
    }
}

val file = new File("date.txt")
withPrintWriter(file) {
    writer => writer.println(new java.util.Date)
} // 중괄호로 변경

이름에 의한 호출

var assertionsEnabled = true
def myAssert(predicate: () => Boolean) =
    if (assertionsEnabled && !predicate())
        throw new AssertionError

myAssert(() => 5 > 3)

def byNameAssert(predicate: => Boolean) = // 이름에 의한 호출 파라미터
    if (assertionsEnabled && !predicate)
        throw new AssertionError

byNameAssert(5 > 3) // 빈 파라미터 타입 생략 가능

def boolAssert(predicate: Boolean) =
    if (assertionsEnabled && !predicate)
        throw new AssertionError

boolAssert(5 > 3)   // 괄호 안의 표현식이 바로 실행됨


+ Recent posts