Skip to content
LoveAg edited this page Jun 13, 2017 · 1 revision

14์žฅ. ๋‹จ์–ธ๋ฌธ๊ณผ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ

14.1 ๋‹จ์–ธ๋ฌธ

  • assert ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋‹จ์–ธ๋ฌธ์„ ์ž‘์„ฑํ•˜๋ฉฐ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ AssertionError๋ฅผ ๋˜์ง„๋‹ค.
  • assert(c, e) ๋‘ ๊ฐœ ์ธ์ž๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ : ์กฐ๊ฑด c๋ฅผ ๋งŒ์กฑํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์„ค๋ช… e๋ฅผ ํฌํ•จํ•˜๋Š” AssertionError๋ฅผ ๋˜์ง„๋‹ค. : e๋Š” Any ํƒ€์ž…์œผ๋กœ AssertionError๊ฐ์ฒด์— e.toString์„ ํ˜ธ์ถœํ•œ๋‹ค.
  • ensuring ๋ฉ”์†Œ๋“œ๋Š” ์ˆ ์–ด ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ณ  true, false๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

14.2 ๋‹จ์œ„ ํ…Œ์ŠคํŠธ

  • ์ž๋ฐ”๋„๊ตฌ JUnit, TestNG
  • ์Šค์นผ๋ผ๋กœ ๋งŒ๋“ค์–ด์ค€ ScalaTest, specs, ScalaCheck ๋“ฑ๋„ ์žˆ๋‹ค
    • org.scalatest.Suite ํ™•์žฅ ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•˜์—ฌ test๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๊ณ  execute()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์Šค์œ„ํŠธ ์•ˆ์— ์žˆ๋Š” ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๋ฅผ ์ฐพ์•„์„œ ์‹คํ–‰
    • org.scalatest.FunSuite ํ™•์žฅ ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•˜์—ฌ test ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๊ณ  ๊ทธ ์•ˆ์— ์ฝ”๋“œ ๊ธฐ์ž…

14.3 ์‹คํŒจ ๋ณด๊ณ  ์‹œ ๋” ๋งŽ์€ ์ •๋ณด ์ œ๊ณตํ•˜๊ธฐ

  • === ์—ฐ์‚ฐ์ž, expect ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์‹œ์ง€ ๋‚˜ํƒ€๋‚ด๊ธฐ
  • ScalaTest์˜ intercept ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์™ธ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ

14.4 JUnit๊ณผ TestNG ์‚ฌ์šฉ

14.5 ๋ช…์„ธ๋ฅผ ํ…Œ์ŠคํŠธ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ

  • ๋™์ž‘ ์ฃผ๋„ ๊ฐœ๋ฐœ ํ…Œ์ŠคํŠธ ์Šคํƒ€์ผ ScalaTest์—์„œ Spec, WordSpec, FlatSpec, FeatureSepc ๋“ฑ์„ ์ œ๊ณต

14.6 ํ”„๋กœํผํ‹ฐ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ



15์žฅ. ์ผ€์ด์Šค ํด๋ž˜์Šค์™€ ํŒจํ„ด ๋งค์น˜

15.1 ๊ฐ„๋‹จํ•œ ์˜ˆ

  • ์ผ€์ด์Šค ํด๋ž˜์Šค : ํด๋ž˜์Šค ์„ ์–ธ์—์„œ case ์ˆ˜์‹์ž๋ฅผ ๋„ฃ์Œ
    1. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํด๋ž˜์Šค ์ด๋ฆ„๊ณผ ๊ฐ™์€ ์ด๋ฆ„์˜ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. new ์—†์ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

    2. ํŒŒ๋ผ๋ฏธํ„ฐ ๋ชฉ๋ก์— ์žˆ๋Š” ๋ชจ๋“  ํด๋ž˜์Šค ํŒŒ๋ผ๋ฏธํ„ฐ์— ์•”์‹œ์ ์œผ๋กœ val ์ ‘๋‘์‚ฌ๋ฅผ ๋ถ™์ธ๋‹ค. ๊ฐ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ํด๋ž˜์Šค์˜ ํ•„๋“œ๋„ ๋œ๋‹ค.
    3. toString, hashCode, equals ๋ฉ”์†Œ๋“œ์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด ๊ตฌํ˜„์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
    4. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ผ€์ด์Šค ํด๋ž˜์Šค์—์„œ ์ผ๋ถ€๋ฅผ ๋ณ€๊ฒฝํ•œ ๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•˜๋Š” copy ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

abstract class Expr
case class Var(name: String) extends Expr
case class Number(num:  Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr

object HelloWorld {
    def main(args: Array[String]) {
        val v = Var("x")
        val op = BinOp("+", Number(1), v)
        
        println("v.name : " + v.name)
        println("op.left : " + op.left)
        
        println("op : " + op)
        println("op.right == Var(x) : " + (op.right == Var("x")))
        
        val op2 = op.copy(operator = "-")
        println("op.copy(operator = -) : " + op2)     
        println("op == op2 : " + (op == op2))
    }
}

[๊ฒฐ๊ณผ]
v.name : x
op.left : Number(1.0)
op : BinOp(+,Number(1.0),Var(x))
op.right == Var(x) : true
op.copy(operator = -) : BinOp(-,Number(1.0),Var(x))
op == op2 : false

  • ํŒจํ„ด ๋งค์น˜

    • ์…€๋ ‰ํ„ฐ match { ๋Œ€์•ˆ๋“ค }
    • ํŒจํ„ด ๋งค์น˜์—๋Š” case ํ‚ค์›Œ๋“œ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋Œ€์•ˆ๋“ค์ด ๋“ค์–ด๊ฐ€๊ณ  ๊ฐ ๋Œ€์•ˆ์€ ํŒจํ„ด๊ณผ => ์‹ฌ๋ณผ๋กœ ๋ถ„๋ฆฌ๋˜๋Š” ํŒจํ„ด๊ณผ ์ผ์น˜ํ–ˆ์„ ๋•Œ ๊ณ„์‚ฐํ•  ํ‘œํ˜„์‹์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
  • switch์™€ match์˜ ๋น„๊ต
    1. ์Šค์นผ๋ผ์˜ match๋Š” ํ‘œํ˜„์‹์ด๊ณ  ๊ฒฐ๊ณผ ๊ฐ’์„ ๋‚ด๋†“๋Š”๋‹ค.
    2. ์Šค์นผ๋ผ์˜ case๋Š” ๋‹ค์Œ case๋กœ ๋น ์ง€์ง€ ์•Š๋Š”๋‹ค. (break ๋ถˆํ•„์š”)
    3. ๋งค์น˜์— ์„ฑ๊ณตํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ MatchError ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ๋””ํดํŠธ ์ผ€์ด์Šค๋ฅผ ๋ฐ˜๋“œ์‹œ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.


val t = "a"
t match {
    case "b" => println("b")
}
[๊ฒฐ๊ณผ]
Exception in thread "main" scala.MatchError: a (of class java.lang.String)

15.2 ํŒจํ„ด์˜ ์ข…๋ฅ˜

  • ์™€์ผ๋“œ์นด๋“œ ํŒจํ„ด : ์–ด๋–ค ๊ฐ์ฒด๋ผ๋„ ๋งค์น˜ํ•  ์ˆ˜ ์žˆ๊ณ  ์–ด๋–ค ๊ฐ์ฒด์—์„œ ๊ฐ’์„ ์•Œ ํ•„์š”๊ฐ€ ์—†๋Š” ๋ถ€๋ถ„์„ ๋ฌด์‹œํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

def matchTest(arg: Expr){
    arg match{
        case BinOp(_, _, _) => println(arg + " is a binary operation")
        case _ => println("It's somethisng else")
    }
}

matchTest(op)
matchTest(v)

[๊ฒฐ๊ณผ]
BinOp(+,Number(1.0),Var(x)) is a binary operation
It's somethisng else

  • ์ƒ์ˆ˜ ํŒจํ„ด : ์ž์‹ ๊ณผ ๋˜‘๊ฐ™์€ ๊ฐ’๊ณผ ๋งค์น˜๋˜๋ฉฐ ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋ฆฌํ„ฐ๋Ÿด์ด๋“  ์ƒ์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ณ€์ˆ˜ ํŒจํ„ด : ์™€์ผ๋“œ์นด๋“œ์ฒ˜๋Ÿผ ์–ด๋–ค ๊ฐ์ฒด์™€๋„ ๋งค์น˜๋˜๋‚˜ ๋ณ€์ˆ˜ ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•œ๋‹ค.

  • ๋ณ€์ˆ˜ ๋˜๋Š” ์ƒ์ˆ˜?

    • ์†Œ๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ด๋ฆ„์€ ํŒจํ„ด ๋ณ€์ˆ˜๋กœ ์ทจ๊ธ‰ํ•˜๊ณ  ๋‹ค๋ฅธ ๋ชจ๋“  ์ฐธ์กฐ๋Š” ์ƒ์ˆ˜๋กœ ๊ฐ„์ฃผํ•œ๋‹ค.
    • ๋””ํดํŠธ ์ผ€์ด์Šค๋ฅผ ์ถ”๊ฐ€ ์‹œ ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒ(Warning ๋ฐœ์ƒํ•˜๋Š” ๋“ฏ)
    • ์†Œ๋ฌธ์ž ์ด๋ฆ„์„ ์ƒ์ˆ˜ ํŒจํ„ด์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๊ธด ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์—ญ๋”ฐ์˜ดํ‘œ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ๊ฐ์‹ธ๋ฉด ๋œ๋‹ค
  • ์ƒ์„ฑ์ž ํŒจํ„ด : ์–ด๋–ค ๊ฐ’์ด ํ•ด๋‹น ์ผ€์ด์Šค ํด๋ž˜์Šค์— ์†ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•œ ๋‹ค์Œ ๊ทธ ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž๊ฐ€ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›์€ ๊ฐ’๋“ค์ด ๊ด„ํ˜ธ ์•ˆ์˜ ํŒจํ„ด๊ณผ ์ •ํ™•ํžˆ ๋งค์น˜๋  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์Šค์นผ๋ผ ํŒจํ„ด์ด ๊นŠ์€ ๋งค์น˜๋ฅผ ์ง€์›ํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.


def deepMatchTest(expr: Expr){
      expr match {
        case BinOp("+", Number(1), v) => println("a deep match")
        case _ => println("no match")
      }
}

val opA = BinOp("+", Number(1), v)
val opB = opA.copy(operator = "-")
val opC = BinOp("+", Number(0), opA)
deepMatchTest(opA)
deepMatchTest(opB)
deepMatchTest(opC)

[๊ฒฐ๊ณผ]
a deep match
no match
no match

  • ์‹œํ€€์Šค ํŒจํ„ด : ๋ฐฐ์—ด์ด๋‚˜ ๋ฆฌ์ŠคํŠธ ๊ฐ™์€ ์‹œํ€€์Šค ํƒ€์ž…์— ๋Œ€ํ•ด์„œ๋„ ๋งค์น˜์‹œํ‚ฌ ์ˆ˜ ์žˆ์œผ๋ฉฐ ํŒจํ„ด ๋‚ด๋ถ€์— ์›ํ•˜๋Š” ๊ฐœ์ˆ˜๋งŒํผ ์›์†Œ๋ฅผ ๋ช…์‹œํ•˜๊ณ  ๊ธธ์ด๋ฅผ ํ•œ์ •ํ•˜์ง€ ์•Š๊ณ  ๋งค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

expr match{
    case List(0, _, _) => println("found it")
    case List(0, _*) => println("found it")
    case _ =>
}
  • ํŠœํ”Œ ํŒจํ„ด : ํŠœํ”Œ๋„ ๋งค์น˜ ๊ฐ€๋Šฅ (case(a, b, c) => println("matched" + a + b + c))
  • ํƒ€์ž… ์ง€์ • ํŒจํ„ด : ํƒ€์ž… ๊ฒ€์‚ฌ๋‚˜ ํƒ€์ž… ๋ณ€ํ™˜์„ ๋Œ€์‹ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋ฉฐ ํŠนํžˆ ํƒ€์ž… ๊ฒ€์‚ฌ์™€ ๋ณ€ํ™˜์„ ๋™์‹œ์— ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์œ ์šฉํ•˜๋‹ค.

def fun(x: Any) = x match {
    case s: String => s.length
    case m: Map[_, _] => m.size
    case _ => -1
}
์œ„์™€ ๊ฐ™์€ ๋™์ž‘์„ isInstanceOf[typeVal] ์™€ asInstanceOf[typeVal] ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ ์ฝ”๋“œ๊ฐ€ ๋” ๊ธธ์–ด์ง€๊ณ  ๋ณต์žกํ•ด์ง
  • ์Šค์นผ๋ผ๋Š” ์ž๋ฐ”์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ œ๋„ค๋ฆญ์—์„œ ํƒ€์ž… ์†Œ๊ฑฐ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— match๋ฅผ ํ†ตํ•ด ์›์†Œ ํƒ€์ž… ํ™•์ธ์ด ์–ด๋ ต์ง€๋งŒ ๋ฐฐ์—ด์€ ์›์†Œ ํƒ€์ž…๊ณผ ๊ฐ’์„ ํ•จ๊ป˜ ์ €์žฅํ•˜๋ฏ€๋กœ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋ณ€์ˆ˜ ๋ฐ”์ธ๋”ฉ : @ ๊ธฐํ˜ธ๋ฅผ ๋„ฃ๊ณ  ํŒจํ„ด์„ ์“ฐ๋ฉด ์ผ๋ฐ˜์ ์ธ ๋งค์น˜๋ฅผ ์‹œ๋„ํ•˜๊ณ  ๊ทธ ํŒจํ„ด ๋งค์น˜์— ์„ฑ๊ณตํ•˜๋ฉด ๋ณ€์ˆ˜๊ฐ€ ํ•˜๋‚˜ ์žˆ๋Š” ํŒจํ„ด์—์„œ์ฒ˜๋Ÿผ ๋งค์น˜๋œ ๊ฐ์ฒด๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅํ•œ๋‹ค.

15.3 ํŒจํ„ด ๊ฐ€๋“œ

ํŒจํ„ด ๋’ค์— ์˜ค๊ณ  if๋กœ ์‹œ์ž‘ํ•˜๋ฉฐ ํŒจํ„ด ์•ˆ์— ์žˆ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์–ด๋–ค ๋ถˆ๋ฆฌ์–ธ ํ‘œํ˜„์‹๋„ ๊ฐ€๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ€๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ๊ฐ€๋“œ๊ฐ€ true๊ฐ€ ๋  ๋•Œ๋งŒ ๋งค์น˜์— ์„ฑ๊ณตํ•œ๋‹ค.


case n: Int if 0 < n => ...  // ์–‘์˜ ์ •์ˆ˜๋งŒ ๋งค์น˜
case s: String if s == 'a' => ... // 'a'๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฌธ์ž์—ด๋งŒ ๋งค์น˜

15.4 ํŒจํ„ด ๊ฒน์นจ

case๋ฌธ์˜ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜๋ฉฐ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” case๋ฌธ์˜ ์œ„์น˜๊ฐ€ ์ƒ์œ„์— ์žˆ์„ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒฝ๊ณ  ํ‘œ์‹œ๋ฅผ ํ•œ๋‹ค. (error : unreachable code)

15.5 ๋ด‰์ธํ•œ ํด๋ž˜์Šค

  • ์ตœ์ƒ์œ„ ์Šˆํผ ํด๋ž˜์Šค ์•ž์— sealed ํ‚ค์›Œ๋“œ๋ฅผ ์„ ์–ธํ•˜์—ฌ ๊ทธ ํด๋ž˜์Šค์™€ ๊ฐ™์€ ํŒŒ์ผ์ด ์•„๋‹Œ ๋‹ค๋ฅธ ๊ณณ์—์„œ๋Š” ์ƒˆ๋กœ์šด ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๋„๋ก ํ•œ๋‹ค.
  • ๋ด‰์ธํ•œ ํด๋ž˜์Šค๋Š” ํŒจํ„ด ๋งค์น˜์—์„œ ์œ ์šฉํ•˜๋ฉฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ๋†“์นœ ํŒจํ„ด ์กฐํ•ฉ์„ ํ™˜๊ธฐ์‹œ์ผœ์ค€๋‹ค.
  • ๋งค์น˜์˜ ์…€๋ ‰ํ„ฐ์— @unchecked ์• ๋…ธํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ case๋ฌธ์ด ๋ชจ๋“  ํŒจํ„ด์„ ๋‹ค ๋‹ค๋ฃจ๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์„ ์ƒ๋žตํ•˜์—ฌ ๋†“์นœ ํŒจํ„ด์— ๋Œ€ํ•œ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ์•ˆ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

15.6 Option ํƒ€์ž…

  • Option์ด๋ผ๋Š” ํ‘œ์ค€ ํƒ€์ž…์€ ์„ ํƒ์ ์ธ ๊ฐ’์„ ํ‘œํ˜„ํ•˜๋ฉฐ ๊ฐ’์ด ์žˆ์„ ๊ฒฝ์šฐ Some(x), ์—†์œผ๋ฉด None์ด๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ๋œ๋‹ค.
  • ์Šค์นผ๋ผ ์ปฌ๋ ‰์…˜์˜ ๋ช‡๋ช‡ ํ‘œ์ค€ ์—ฐ์‚ฐ์€ ์„ ํƒ์ ์ธ ๊ฐ’์„ ์ƒ์„ฑํ•˜๊ณ  ์ด ์˜ต์…˜ ๊ฐ’์„ ๋ถ„๋ฆฌํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ ํŒจํ„ด ๋งค์น˜์ด๋‹ค.

val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")
println("capitals get France : " + (capitals get "France"))         // capitals get France : Some(Paris)
println("capitals get North Pole : " + (capitals get "North Pole")) // capitals get North Pole : None

def show(x: Option[String]): String = {
    x match {
        case Some(s) => s
        case None => "????"
    }
}
println("capitals get France : " + show(capitals get "France"))         // capitals get France : **Paris**
println("capitals get North Pole : " + show(capitals get "North Pole")) // capitals get North Pole : **????**
  • null์ด ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ๋งˆ๋‹ค null ๊ฒ€์‚ฌ๋ฅผ ํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ณ  NullPointerException์„ ๋ฐœ์ƒํ•˜์ง€๋„ ์•Š๋Š”๋‹ค. option ์‚ฌ์šฉ์œผ๋กœ ์ธํ•ด null์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์—์„œ ์Šค์นผ๋ผ๋Š” ํƒ€์ž… ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒํ•œ๋‹ค. ์–ด๋–ค ๋ณ€์ˆ˜๊ฐ€ Option[String] ํƒ€์ž…์ด๋ผ๋ฉด, ๊ทธ ๋ณ€์ˆ˜๋ฅผ String์œผ๋กœ ์‚ฌ์šฉํ•˜๋ ค ํ•˜๋Š” ์Šค์นผ๋ผ ํ”„๋กœ๊ทธ๋žจ์€ ์ปดํŒŒ์ผ์„ ํ•  ์ˆ˜ ์—†๋‹ค.

val optionSize = (capitals get "France").length()  // **Compile Error : value length is not a member of Option[String]**
val noralsize = (show(capitals get "France")).length()

15.7 ํŒจํ„ด์€ ์–ด๋””์—๋‚˜

  • ๋ณ€์ˆ˜ ์ •์˜์—์„œ ํŒจํ„ด ์‚ฌ์šฉํ•˜๊ธฐ : val์ด๋‚˜ var๋ฅผ ์ •์˜ํ•  ๋•Œ, ํŒจํ„ด์„ ์‚ฌ์šฉ. ์ผ€์ด์Šค ํด๋ž˜์Šค์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉฐ ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด ๊ฐ’์ผ ํ•ด์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.

val exp = new BinOp("%", Number(5), Number(1))
val BinOp(opr, left, right) = exp
println("opr : " + opr + ", left : " + left + ", right : " + right)



16์žฅ. ๋ฆฌ์ŠคํŠธ

16.1 ๋ฆฌ์ŠคํŠธ ๋ฆฌํ„ฐ๋Ÿด

  • ๋ฐฐ์—ด๊ณผ ๋น„์Šทํ•˜๋‚˜ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ  ์žฌ๊ท€์ ์ด๋‹ค. (์˜ˆ : linked list)

16.2 ๋ฆฌ์ŠคํŠธ ํƒ€์ž…

  • ๋ฆฌ์ŠคํŠธ ํƒ€์ž…์€ ๊ณต๋ณ€์ ์ด๋‹ค.
  • ๋นˆ ๋ฆฌ์ŠคํŠธ์˜ ํƒ€์ž…์ด List[Nothing]์ด๋ฉฐ Noting์€ ํด๋ž˜์Šค ๊ณ„์ธต๊ตฌ์กฐ์˜ ๋งจ ์•„๋ž˜ ํƒ€์ž…์ด๋ฏ€๋กœ List()๋Š” List[String] ํƒ€์ž…์ด๊ธฐ๋„ ํ•˜๋‹ค.

16.3 ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ

  • Nil์€ ๋นˆ๋ฆฌ์ŠคํŠธ๋ฅผ ์˜๋ฏธํ•˜๊ณ  ::๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์•ž์— ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

val nums: List[Int] = List(1, 2, 3, 4)
val nums = 1 :: 2 :: 3 :: 4 :: Nil

16.4 ๋ฆฌ์ŠคํŠธ ๊ธฐ๋ณธ ์—ฐ์‚ฐ

  • head : ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ๋ฒˆ์งธ ์›์†Œ
  • tail : ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ์›์†Œ๋กœ ์ด๋ค„์ง„ ๋ฆฌ์ŠคํŠธ
  • isEmpty : ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ๋‹ค๋ฉด true๋ฅผ ๋ฐ˜ํ™˜

16.5 ๋ฆฌ์ŠคํŠธ ํŒจํ„ด

ํŒจํ„ด ๋งค์น˜๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.


val fruit: List[String] = List("apple", "orange", "pear", "melon", "grape")
val a :: b :: rest = fruit
println("a : " + a)
println("b : " + b)
println("rest : " + rest)

[๊ฒฐ๊ณผ]
a : apple
b : orange
rest : List(pear, melon, grape)

16.6 List ํด๋ž˜์Šค์˜ 1์ฐจ ๋ฉ”์†Œ๋“œ

  • ๋‘ ๋ฆฌ์ŠคํŠธ ์—ฐ๊ฒฐํ•˜๊ธฐ : ":::" ๋‘ ์ธ์ž๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ›์•„ ์—ฐ๊ฒฐํ•œ๋‹ค.
  • ๋ถ„ํ•  ์ •๋ณต ์›์น™ : ??
  • ๋ฆฌ์ŠคํŠธ ๊ธธ์ด ๊ตฌํ•˜๊ธฐ: length - ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜์—ฌ ๊ฒ€์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›์†Œ ๊ฐœ์ˆ˜๋งŒํผ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ๋‹ค.
    1. ๋ฆฌ์ŠคํŠธ ์–‘ ๋์— ์ ‘๊ทผํ•˜๊ธฐ: init, last (head ๋ฐ tail๊ณผ ๋‹ฌ๋ฆฌ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•œ๋‹ค.)
      init : ๋งˆ์ง€๋ง‰ ์›์†Œ๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ์›์†Œ๋ฅผ ํฌํ•จํ•œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜
      last : ๋งˆ์ง€๋ง‰ ์›์†Œ๋ฅผ ๋ฐ˜ํ™˜
    2. ๋ฆฌ์ŠคํŠธ ๋’ค์ง‘๊ธฐ: reverse ๋ฆฌ์ŠคํŠธ์˜ ๋’ค์ง‘์–ด ์ƒˆ๋กœ์šด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
    3. ์ ‘๋‘์‚ฌ์™€ ์ ‘๋ฏธ์‚ฌ: drop, take, splitAt
      drop : ์ฒซ๋ฒˆ์งธ์—์„œ n๋ฒˆ์งธ๊นŒ์ง€ ์›์†Œ๋ฅผ ์ œ์™ธํ•œ ๋ฆฌ์ŠคํŠธ ์›์†Œ๋“ค ๋ฐ˜ํ™˜
      take : n ๋ฒˆ์งธ๊นŒ์ง€ ์›์†Œ๋ฅผ ๋ฐ˜ํ™˜
      splitAt : n๋ฒˆ์งธ ์ธ๋ฑ์Šค ์œ„์น˜์—์„œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ถ„ํ• ํ•˜์—ฌ ๋ฐ˜ํ™˜
    4. ์›์†Œ ์„ ํƒ: apply์™€ indices
      apply : n ๋ฒˆ์งธ ์ธ๋ฑ์Šค ์›์†Œ๋ฅผ ๋ฐ˜ํ™˜
      indices : ์œ ํšจํ•œ ๋ชจ๋“  ์ธ๋ฑ์Šค์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜
    5. ๋ฆฌ์ŠคํŠธ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•œ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜๋“ฏํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ: flatten
      flatten : ๋ฆฌ์ŠคํŠธ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜๋“ฏํ•˜๊ฒŒ ํŽผ์นœ๋‹ค.
    6. ๋‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœ์„œ์Œ์œผ๋กœ ๋ฌถ๊ธฐ: zip๊ณผ unzip
      zip : ๋‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ์ˆœ์„œ์Œ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด ๊ธธ์ด๊ฐ€ ๋‹ค๋ฅด๋ฉด ๊ธด ์ชฝ์˜ ๋‚จ๋Š” ์›์†Œ๋ฅผ ๋ฒ„๋ฆฐ๋‹ค.
      zipWithIndex : ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ์›์†Œ์™€ ๊ทธ ์œ„์น˜๋ฅผ ๋ฌถ๋Š”๋‹ค.
      unzip : ํŠœํ”Œ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฆฌ์ŠคํŠธ๋ฆ ํŠœํ”Œ๋กœ ๋ฐ”๊พผ๋‹ค.
    7. ๋ฆฌ์ŠคํŠธ ์ถœ๋ ฅํ•˜๊ธฐ: toString, mkString
      toString : ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•œ ํ‘œ์ค€ ๋ฌธ์ž์—ด ํ‘œํ˜„์„ ๋ฐ˜ํ™˜
      mkString : ์ ‘๋‘์‚ฌ ๋ฌธ์ž์—ด, ๋ถ„๋ฆฌ ๋ฌธ์ž์—ด, ์ ‘๋ฏธ์‚ฌ ๋ฌธ์ž์—ด์„ ๋ฐ›์•„ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜
      addString : mkString๊ณผ ์œ ์‚ฌํ•˜๋‚˜ StringBuilder๊ฐ์ฒด์— ์ถ”๊ฐ€
    8. ๋ฆฌ์ŠคํŠธ ๋ณ€ํ™˜ํ•˜๊ธฐ: iterator, toArray, copyToArray
      iterator : ๋ฆฌ์ŠคํŠธ ์›์†Œ๋ฅผ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ ‘๊ทผ
      toArray, toList : List <-> Array ๋ณ€ํ™˜
      copyToArray : ๋ฆฌ์ŠคํŠธ ์›์†Œ๋ฅผ ๋ฐฐ์—ด์˜ ํŠน์ • ์ง€์ ๋ถ€ํ„ฐ ์—ฐ์†์ ์œผ๋กœ ๋ณต์‚ฌ

16.7 List ํด๋ž˜์Šค์˜ ๊ณ ์ฐจ ๋ฉ”์†Œ๋“œ

  1. ๋ฆฌ์ŠคํŠธ ๋งคํ•‘: map, flatMap, foreach
    map : ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•จ์ˆ˜์— ์ ์šฉํ•˜์—ฌ ๊ทธ ๊ฒฐ๊ณผ ๊ฐ’์œผ๋กœ ์ด๋ค„์ง„ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜
    flatMap : map๊ณผ ์œ ์‚ฌํ•˜๋‚˜ ๊ฒฐ๊ณผ ๋ฆฌ์ŠคํŠธ๋ฅผ ์„œ๋กœ ์—ฐ๊ฒฐํ•œ ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜
    foreach : ์˜ค๋ฅธ์ชฝ ํ”ผ์—ฐ์‚ฐ์ž๋กœ ํ”„๋กœ์‹œ์ €๋ฅผ ๋ฐ›์•„ ์ ์šฉ
  2. ๋ฆฌ์ŠคํŠธ ๊ฑธ๋Ÿฌ๋‚ด๊ธฐ:filter, partition, find, takeWhile, dropWhile, span
    filter : Boolean ํƒ€์ž…์˜ ์ˆ ์–ด ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•„์„œ true์ธ ์›์†Œ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜
    partition : filter์™€ ๊ฐ™์ด ์ˆ ์–ด ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•„์„œ true, false ๊ฐ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜
    find : filter์™€ ์œ ์‚ฌํ•˜๋‚˜ ์ˆ ์–ด ํ•จ์ˆ˜์— ๋งŒ์กฑํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์›์†Œ๋งŒ ๋ฐ˜ํ™˜
    takeWhile : ์ˆ ์–ด ํ•จ์ˆ˜๋ฅผ ๋งŒ์กฑํ•˜๋Š” ๊ฐ€์žฅ ๊ธด ์ ‘๋‘์‚ฌ๋ฅผ ๋ฐ˜ํ™˜
    dropWhile : ์ˆ ์–ด ํ•จ์ˆ˜๋ฅผ ๋งŒ์กฑํ•˜๋Š” ๊ฐ€์žฅ ๊ธด ์ ‘๋‘์‚ฌ๋ฅผ ์ œ๊ฑฐ
    span : takeWhile, dropWhile์„ ํ•˜๋‚˜๋กœ ๋ฌถ์€ ๊ฒƒ
  3. ๋ฆฌ์ŠคํŠธ ์ „์ฒด์— ๋Œ€ํ•œ ์ˆ ์–ด: forall๊ณผ exists
    forall : ๋ชจ๋“  ์›์†Œ๊ฐ€ ์ˆ ์–ด ํ•จ์ˆ˜๋ฅผ ๋งŒ์กฑํ•  ๋•Œ true๋ฅผ ๋ฐ˜ํ™˜
    exists : ์ˆ ์–ด ํ•จ์ˆ˜๋ฅผ ๋งŒ์กฑํ•˜๋Š” ์›์†Œ๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ์กด์žฌํ•˜๋ฉด true๋ฅผ ๋ฐ˜ํ™˜
  4. ๋ฆฌ์ŠคํŠธ ํด๋“œ: /:, :<br/> fold์—ฐ์‚ฐ : ์™ผ์ชฝํด๋“œ /: ์˜ค๋ฅธ์ชฝ ํด๋“œ :\ ์ „๋‹ฌ๋ฐ›๋Š” ์—ฐ์‚ฐ์ž๋ฅผ ๊ฐ ๋ฐฉํ–ฅ์œผ๋กœ ๋ถ€ํ„ฐ ์—ฐ์† ์ ์šฉ
  5. ๋ฆฌ์ŠคํŠธ ์ •๋ ฌ: sortWith
    sortWith : List sortWith before ํ˜•์‹์œผ๋กœ before ์ž๋ฆฌ์— ์ •์˜๋œ ๋น„๊ตํ•จ์ˆ˜๋Œ€๋กœ ์ •๋ ฌ (์˜ˆ : ListX sortWith (_ < _))

16.8 List ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ

  1. ์›์†Œ๋กœ๋ถ€ํ„ฐ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ: List.apply
    List.apply : List.apply(1,2,3) == List(1, 2, 3)
  2. ์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ๋งŒ๋“ค๊ธฐ: List.range
    List.range : ์–ด๋–ค ๋ฒ”์œ„๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์ˆ˜๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค. List.range(from, until, increment)
  3. ๊ท ์ผํ•œ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ: List.fill
    List.fill : ์ƒ์„ฑํ•  ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด์™€ ๋ฐ˜๋ณตํ•  ์›์†Œ๋ฅผ ๋ฐ›์•„ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ฑ„์›€ (์˜ˆ : List.fill(5)('a'), List.fill(2,3)('b'))
  4. ํ•จ์ˆ˜ ๋„ํ‘œํ™”:List.tabulate
    List.tabulate : ์ œ๊ณต๋œ ํ•จ์ˆ˜๋กœ ๊ณ„์‚ฐํ•œ ์›์†Œ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑ (์˜ˆ : List.tabulate(5)(n => n * n), List.tabulate(5,5)(*))
  5. ์—ฌ๋Ÿฌ ๋ฆฌ์ŠคํŠธ ์—ฐ๊ฒฐํ•˜๊ธฐ: List.concat
    List.concat : ์—ฌ๋Ÿฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค. (์˜ˆ : list.concat(List(), List('a'), List('b'))

16.9 ์—ฌ๋Ÿฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•จ๊ป˜ ์ฒ˜๋ฆฌํ•˜๊ธฐ

Clone this wiki locally