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


7장

if 표현식

var filename = "default.txt"
if (!args.isEmpty)
  filename = args(0)
val filename =
  if (!args.isEmpty) args(0)
  else "default.txt"

while 루프

  • 수행 결과는 Unit 타입
  • 할당의 결과는 Unit 값(())
(line == readLine()) != "" // () != "" 이므로 항상 참

while

while (a != 0) {
    val temp = a
    a = b%a
    b = temp
}

do-while

do {
    line = readLine()
    println("Read: " + line)
} while (line != "")

for 표현식

컬렉션 순회

  • 배열 순회
val filesHere = (new java.io.File(".")).listFiles
for (file <- filesHere)
  println(file)
  • Range 순회
for (i <- 1 to 4) // 1,2,3,4
  println("Iteration "+i)
for (i <- 1 until 4) // 1,2,3
  println("Iteration "+i)

필터링

val filesHere = (new java.io.File(".")).listFiles
for (file <- filesHere if file.getName.endsWith(".scala")) // '.scala'로 끝나는 파일만
  println(file)
for {
    file <- filesHere
    if file.isFile // 필터 추가
    if file.getName.endsWith(".scala")
} println(file)

중첩 순회

def fileLines(file: java.io.File) =
  scala.io.Source.fromFile(file).getLines().toList

def grep(pattern: String) =
  for {
    file <- fileHere
    if file.getName.endsWith(".scala")  // 바깥 루프
    line <- fileLines(file)
    if line.trim.matches(pattern)  // 안쪽 루프
   } println(file +": "+ line.trim)

grep(".*gcd.*")

변수 바인딩

def fileLines(file: java.io.File) =
  scala.io.Source.fromFile(file).getLines().toList

def grep(pattern: String) =
  for {
    file <- fileHere
    if file.getName.endsWith(".scala")
    line <- fileLines(file)
    trimmed = line.trim  // val 변수 처럼 선언하고 사용
    if trimmed.matches(pattern)
  } println(file +": "+ trimmed)

grep(".*gcd.*")

컬렉션 생성

def scalaFiles =
  for {
    file <- filesHere
    if file.getName.endsWith(".scala")
  } yield file
  • yield 는 전체 본문의 앞에 위치

try 표현식

예외 발생

throw new IllegalArgumentException // throw
  • throw는 Nothing이라는 타입을 결과값으로 갖는다.

예외 잡기

try {
  val f = new FileReader("input.txt")
} catch {
  case ex: FileNotFoundException => // ...
  case ex: IOExceptoin => // ...
}

finally 절

val file = new FileReader("input.txt")
try {
  // ...
} finally {
  file.close()
}

결과값

  • try, catch 값이 결과값으로 사용됨
  • finally는 결과값을 바꾸지 않음

match 표현식

  • case 내에는 어떤 종류의 상수라도 사용 가능
  • 모든 case마다 break문이 암묵적으로 존재
val firstArg = if (args.length > 0) args(0) else ""
firstArg match {
  case "salt" => println("pepper")
  case "chips" => println("salsa")
  case "eggs" => println("bacon")
  case _ => println("huh?")     // default case
}

break / continue

  • continue -> if
  • break -> 불리언 변수
  • 재귀 함수 사용(꼬리 재귀 호출)
  • scala.util.control.Breaks 클래스
import scala.util.control.Breaks._
import java.io._

val in = new BufferedReader(new InputStreamReader(System.in))

breakable {
    while (true) {
        println("? ")
        if (in.readLine() == "") break
    }
}

변수 스코프

  • 중괄호 사용시 새로운 스코프 생성(예외 존재 - for 등)
  • 안쪽 스코프에서 바깥 스코프의 동일 이름 변수를 선언하면 바깥 변수는 가려짐(shadow)
  • 인터프리터는 구문마다 새로운 스코프 생성


+ Recent posts