Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scalaリファクタリング入門「大改造!静的ビフォー・アフター」

 Scalaリファクタリング入門「大改造!静的ビフォー・アフター」

「Better Javaの一歩先へ! Scalaリファクタリング入門」@ビズリーチD3勉強会 第一部の資料です。

Shunsuke Tadokoro

December 05, 2016
Tweet

More Decks by Shunsuke Tadokoro

Other Decks in Programming

Transcript

  1. େ վ ଄ ʂ ੩ త Ϗ ϑ Υ ʔ

    ɾ Ξ ϑ λ ʔ d 4DBMBϦϑΝΫλϦϯάೖ໳ !UPEPLS . : ✨
  2. ా ॴ  ॣ ༎  ! U P E

    P L S    ג ࣜ ձ ࣾ Ϗ ζ Ϧ ʔ ν  
   ελ ϯόΠ ࣄ ۀ ෦  α ʔ ν ί Ξάϧ ʔϓ 
     ΢ Σ ϒΫ ϩ ʔ ϥ ʔ ͷ ։ ൃ ɾ ӡ ༻       ೥  ݄ ೖ ࣾ    ࡀ   4 D B M B ྺ   ೥  ϲ ݄
  3. ͓ ࿩ ͢͠ Δ ͜ ͱ w ͳͥ#FUUFS+BWBͷઌͳͷ͔ʁ4DBMBΒ͠͞ͷԸܙͱ͸ w ύλʔϯϚονͷύλʔϯΩϟετΛͳͯ҆͘͠શʹ

    w λϓϧΛආ͚Δͦͷ਺ࣈʹҙຯ͸͋Δ͔ʁ w 4DBMBͳྫ֎ॲཧ੒ޭɾࣦഊΛ஋ͱͯ͠දݱ͢Δ w DBTFDMBTTʹ੍໿Λ࣋ͨͤΔSFRVJSFͷར༻ w TFBMFEUSBJUͰ໢ཏੑΛ୲อ͢ΔίϯύΠϥʹ͓ئ͍
  4. ͓ ࿩ ͢͠ Δ ͜ ͱ w ͳͥ#FUUFS+BWBͷઌͳͷ͔ʁ4DBMBΒ͠͞ͷԸܙͱ͸ w ύλʔϯϚονͷύλʔϯΩϟετΛͳͯ҆͘͠શʹ

    w λϓϧΛආ͚Δͦͷ਺ࣈʹҙຯ͸͋Δ͔ʁ w 4DBMBͳྫ֎ॲཧ੒ޭɾࣦഊΛ஋ͱͯ͠දݱ͢Δ w DBTFDMBTTʹ੍໿Λ࣋ͨͤΔSFRVJSFͷར༻ w TFBMFEUSBJUͰ໢ཏੑΛ୲อ͢ΔίϯύΠϥʹ͓ئ͍ ˠ  4 D B M B Λ ֶ ͼ ࢝ Ί ͨ ࠒ ͷ ࣗ ෼ ʹ 
 ɹ  ڭ ͑ͯ ͋ ͛ ͨ ͍ ಺ ༰
  5. ͳ ͥ # F U U F S  +

    B W B ͷ ઌ ͳ ͷ ͔ ʁ
  6. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ
  7. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ
  8. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ ͪΐͬͱ௕͍
  9. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ ίʔυͷ௕͞ͱόάͷೖΓ΍͢͞͸
 ਖ਼ൺྫ͢ΔɻͰ͖Ε͹΋ͬͱ୹͍ͨ͘͠ɻ ͪΐͬͱ௕͍
  10. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ
  11. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ ग़ޱ͕Օॴ
  12. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ ग़ޱ͕Օॴ Ͱ͖Ε͹෼ذ͸গͳ͍΄͏͕
 γϯϓϧͰݎ࿚ɻ
  13. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ
  14. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ ࠶୅ೖՄೳͳม਺
  15. 1 def isBlank(str:String): Boolean = { 2 var strLen =

    0 3 4 if(str == null || { strLen = str.length(); strLen } == 0) { 5 return true 6 } 7 8 var i = 0 9 while( i < strLen ){ 10 if(Character.isWhitespace( str.charAt(i) ) == false){ 11 return false 12 } 13 i += 1 14 } 15 16 return true 17 } # F U U F S  + B W B ͳ ελ Πϧ ࠶୅ೖՄೳͳม਺ ࠶୅ೖՄೳʮঢ়ଶʯΛ࣋ͭͱ͍͏͜ͱɻ
 ঢ়ଶΛؾʹ͢Δඞཁ͕͋Δɻ
  16. 1 def isBlank(str: String): Boolean = 2 Option(str).fold(true)(_.forall(Character.isWhitespace)) w ୹͘ಡΈ΍͘͢

    w ෼ذ͕গͳ͘ w ঢ়ଶΛؾʹ͢Δඞཁͳ͘ 4 D B M B Β ͠ ͍ ελ Πϧ
  17. 1 def isBlank(str: String): Boolean = 2 Option(str).fold(true)(_.forall(Character.isWhitespace)) w ୹͘ಡΈ΍͘͢

    w ෼ذ͕গͳ͘ w ঢ়ଶΛؾʹ͢Δඞཁͳ͘ 4 D B M B Β ͠ ͍ ελ Πϧ ☺ όάͷࠞೖͷՄೳੑ͕Լ͕Δ
  18. 0 Q U J P O ͷ ύ λ ʔϯ

    Ϛ ο ν 1 option match { 2 case Some(x) => println(s"$x is here!") 3 case None => println("oh…") 4 }
  19. γ ʔ έ ϯε ͷ ύ λ ʔϯ Ϛ ο

    ν 1 List("Noel", "Liam", "Gem", "Andy", "Alan") match { 2 case List(_, second, _*) => println(s"Hello $second!") 3 case _ => 4 } 5 // => Hello Liam!
  20. ί ϯε τ ϥ Ϋ λύ λ ʔϯ 1 val

    user = User("Martin", Place("Tokyo", "Shibuya")) 2 3 user match { 4 case User(name, Place(pref, _)) => "$name in $pref" 5 case _ => 6 } 7 // => Martin lives in Tokyo!
  21. ܕ ν Σ ο Ϋ ͱ Ω ϟε τ 1

    def count2x(x: Any): Int = { 2 if (x.isInstanceOf[String]) { 3 x.asInstanceOf[String].length * 2 4 } else if (x.isInstanceOf[Int]) { 5 x.asInstanceOf[Int] * 2 6 } else -1 7 } 8 9 count2x("scala") // 10 10 count2x(7) // 14
  22. ܕ ν Σ ο Ϋ ͱ Ω ϟε τ 1

    def count2x(x: Any): Int = { 2 if (x.isInstanceOf[String]) { 3 x.asInstanceOf[String].length * 2 4 } else if (x.isInstanceOf[Int]) { 5 x.asInstanceOf[Int] * 2 6 } else -1 7 } 8 9 count2x("scala") // 10 10 count2x(7) // 14 ܕνΣοΫ
  23. ܕ ν Σ ο Ϋ ͱ Ω ϟε τ 1

    def count2x(x: Any): Int = { 2 if (x.isInstanceOf[String]) { 3 x.asInstanceOf[String].length * 2 4 } else if (x.isInstanceOf[Int]) { 5 x.asInstanceOf[Int] * 2 6 } else -1 7 } 8 9 count2x("scala") // 10 10 count2x(7) // 14 Ωϟετ
  24. ܕ ν Σ ο Ϋ ͱ Ω ϟε τ 1

    def count2x(x: Any): Int = { 2 if (x.isInstanceOf[String]) { 3 x.asInstanceOf[String].length * 2 4 } else if (x.isInstanceOf[Int]) { 5 x.asInstanceOf[Int] * 2 6 } else -1 7 } 8 9 count2x("scala") // 10 10 count2x(7) // 14 Ωϟετ গ͠৑௕ɻ Θ͟Θ͟Ωϟετ͢Δͷ΋ةݥͳ߳Γɻ ܕνΣοΫ
  25. ܕ ෇ ͖ ύ λ ʔϯ 1 def count2x(x: Any):

    Int = x match { 2 case x:String => x.length * 2 3 case x: Int => x * 2 4 case _ => -1 5 } 6 7 count2x("scala") // 10 8 count2x(7) // 14
  26. ܕ ෇ ͖ ύ λ ʔϯ 1 def count2x(x: Any):

    Int = x match { 2 case x:String => x.length * 2 3 case x: Int => x * 2 4 case _ => -1 5 } 6 7 count2x("scala") // 10 8 count2x(7) // 14 ☺ ίʔυͷݟ௨͕͠޲্ɻ
 Ωϟετ΋ෆཁͰ҆৺ɻ
  27. ܕ ফ ڈ ʹ ஫ ҙ 1 def detectType(x: Any):

    String = x match { 2 case x: List[Int] => "This is List of Int!" 3 case _ => "What?" 4 } 5 6 detectType(List("string!")) // => This is List of Int!
  28. ܕ ফ ڈ ʹ ஫ ҙ 1 def detectType(x: Any):

    String = x match { 2 case x: List[Int] => "This is List of Int!" 3 case _ => "What?" 4 } 5 6 detectType(List("string!")) // => This is List of Int! +BWBͱಉ༷ɺίϨΫγϣϯͷཁૉܕͷ৘ใ͸
 ࣮ߦ࣌ʹ͸؅ཧ͞Εͳ͍ ˞"SSBZΛআ͘
  29. λ ϓϧ 1 // ঎඼ 2 case class Item(name: String,

    price: Int) 3 4 // ঎඼ͷ੫ࠐՁ֨ͱՁ֨ϥϕϧΛฦ͢ 5 def labelPriceWithTax(item: Item): (Int, String) = { 6 val withTax = item.price * 1.08 7 val label = s"ܹ҆େಛՁ ¥${item.price}ʢ੫ࠐʣ" 8 (withTax, label) 9 }
  30. λ ϓϧ 1 // ঎඼ 2 case class Item(name: String,

    price: Int) 3 4 // ঎඼ͷ੫ࠐՁ֨ͱՁ֨ϥϕϧΛฦ͢ 5 def labelPriceWithTax(item: Item): (Int, String) = { 6 val withTax = item.price * 1.08 7 val label = s"ܹ҆େಛՁ ¥${item.price}ʢ੫ࠐʣ" 8 (withTax, label) 9 } ☺ +BWBͰ͸-JTU0CKFDUͷΑ͏ʹฦ͍ͯͨ͠΋ͷ͕
 ܕͷ৘ใΛΩʔϓͨ͠··ฦͤͯ҆৺
  31. Ξ ϯ νύ λ ʔϯ   Ξ ϯ μʔε

    ί Ξ Ͱ ͷ ΞΫ η ε 1 val apple = Item("αϯ;͡", 158) 2 val x = labelPriceWithTax(apple) 3 println(s"${x._1}͕ͳΜͱ${x._2}!") 4 // αϯ;͕͡ͳΜͱܹ҆େಛՁ ¥158!
  32. Ξ ϯ νύ λ ʔϯ   Ξ ϯ μʔε

    ί Ξ Ͱ ͷ ΞΫ η ε 1 val apple = Item("αϯ;͡", 158) 2 val x = labelPriceWithTax(apple) 3 println(s"${x._1}͕ͳΜͱ${x._2}!") 4 // αϯ;͕͡ͳΜͱܹ҆େಛՁ ¥158! ʮY@ʯͷͳͲͷ਺ࣈ͸
 ཁૉʹ͍ͭͯͷ৘ใΛԿ΋఻͍͑ͯͳ͍ɻ
 औΓҧ͑ͯ΋ؾ͖ͮͮΒ͍ɻ
  33. վ ળ ྫ    ม ਺ ୅ ೖ

    ࣌ ʹ λ ϓϧ Λ ෼ ղ 1 val apple = Item("αϯ;͡", 158) 2 val (name, priceLabel) = labelPriceWithTax(apple) 3 println(s"${name}͕ͳΜͱ${priceLabel}!") 4 // αϯ;͕͡ͳΜͱܹ҆େಛՁ ¥158! ҙຯͷ͋Δม਺໊ͰΞΫηεͰ͖ͯ҆৺
 ม਺͕૿͑ͯ΋औΓҧ͑ʹ͍͘ ☺
  34. վ ળ ྫ    ύ λ ʔϯ Ϛ

    ο ν Ͱ λ ϓϧ Λ ෼ ղ 1 val apple = Item("αϯ;͡", 158) 2 labelPriceWithTax(apple) match { case (name, price) => 3 println(s"${name}͕ͳΜͱ${price}!") 4 } 5 // αϯ;͕͡ͳΜͱܹ҆େಛՁ ¥158!
  35. ྫ ֎ ॲ ཧ 1 // ྫ֎Λ౤͛ΔՄೳੑͷ͋Δϝιου 2 def detect(bytes:

    Array[Byte]): Charset = { 3 val detectedCharsetName: String = ... 4 Charset.forName(detectedCharsetName) 5 } 6 7 // ϝιουͷݺͼग़͠ݩͰྫ֎ॲཧ 8 try { 9 detect(bytes) 10 ... 11 } catch { 12 case e: Exception => ... 13 }
  36. ྫ ֎ ॲ ཧ 1 // ྫ֎Λ౤͛ΔՄೳੑͷ͋Δϝιου 2 def detect(bytes:

    Array[Byte]): Charset = { 3 val detectedCharsetName: String = ... 4 Charset.forName(detectedCharsetName) 5 } 6 7 // ϝιουͷݺͼग़͠ݩͰྫ֎ॲཧ 8 try { 9 detect(bytes) 10 ... 11 } catch { 12 case e: Exception => ... 13 } ੒ޭPSࣦഊΛ஋ͱͯ͠ѻ͍ɺ
 ੍ޚϑϩʔΛγϯϓϧʹ͍ͨ͠
  37. ྫ ֎ Ͱ ͸ ͳ ͘ ʜ ੒ޭPSࣦഊΛදݱ͢Δܕͱͦͷ஋Λ༻͍Δ w 0QUJPO<

    5>
 ੒ޭ࣌ͷ஋Λ4PNFɺࣦഊΛ/POFͰදݱ w &JUIFS< "  #>
 ੒ޭ࣌ͷ৘ใΛ3JHIUͰɺࣦഊͷ৘ใΛ-FGUͰදݱ w 5SZ< 5>
 ྫ֎Λ౤͛ΔՄೳੑͷ͋ΔॲཧΛந৅Խɺ4VDDFTTͱ'BJMVSFͰ݁ՌΛදݱ
  38. 0 Q U J P O ܕ w 4PNFͱ/POFͱ͍͏छྨ w

    ஋͕ଘࡏ͢Δ͜ͱΛද͢4PNF W  w ஋͕ଘࡏ͠ͳ͍͜ͱΛද͢/POF w 0QUJPOܕˠʮ஋͕ଘࡏ͠ͳ͍Մೳੑ͕͋Δʯͱ͍͏ϝοηʔδ
  39. 0 Q U J P O Ͱ ੒ ޭ 

    ࣦ ഊ Λ ද ݱ ͢ Δ 1 // try / catchͰOptionΛฦ͢ 2 def detect(bytes: Array[Byte]): Option[Charset] = { 3 val detectedCharsetName: String = ... 4 try { 5 Some(Charset.forName(detectedCharsetName)) 6 } catch { 7 case e: Exception => None 8 } 9 } ੒ޭ࣌͸4PNFɺࣦഊ࣌͸/POFͰฦ͢
  40. 0 Q U J P O Ͱ ੒ ޭ 

    ࣦ ഊ Λ ද ݱ ͢ Δ 1 // ࣦഊͨ͠ΒσϑΥϧτ஋Λ࢖͏ 2 detect(bytes).getOrElse(Charset.defaultCharset) 3 4 // ࣦഊͨ͠ΒԿ΋͠ͳ͍ 5 detect(bytes).map { charset => 6 // Կ͔ॲཧ 7 } ݺͿଆͰͷѻ͍ ݁ՌʹԠͨ͡ॲཧ͕҆શ͔ͭॊೈʹͰ͖Δ ☺
  41. & J U I F S ܕ w 3JHIU D

    ͱ-FGU F ͱ͍͏छྨ w 3JHIU͸ʮਖ਼͍͠ʯʹ͔͚ͯ੒ޭ࣌ͷ஋Λ֨ೲ͢Δͷ͕ओྲྀ w -FGU΋஋Λ࣋ͯΔͷͰɺࣦഊ࣌ͷ৘ใΛ֨ೲͰ͖Δ w &JUIFSܕˠʮࣦഊ͢ΔՄೳੑ͕͋Δʯͱ͍͏ϝοηʔδ
  42. & J U I F S Ͱ ੒ ޭ 

    ࣦ ഊ Λ ද ݱ ͢ Δ 1 // try / catchͰOptionΛฦ͢ 2 def detect(bytes: Array[Byte]): Either[Exception, Charset] = { 3 val detectedCharsetName: String = ... 4 try { 5 Right(Charset.forName(detectedCharsetName)) 6 } catch { 7 case e: Exception => Left(e) 8 } 9 } ੒ޭ࣌͸3JHIUɺࣦഊ࣌͸-FGUͰฦ͢
  43. & J U I F S Ͱ ੒ ޭ 

    ࣦ ഊ Λ ද ݱ ͢ Δ 1 // 2 val charset = detect(bytes) match { 3 case Right(charset) => charset 4 case Left(e) => 5 logger.error(s"Oops! :$e") 6 Charset.defaultCharset 7 } ݺͿଆͰͷѻ͍ ݺͼग़͢ਓʹ݁ՌͷνΣοΫΛڧ੍Ͱ͖Δ
 ࣦഊ࣌ͷ৘ใ͕࣋ͯΔͷͰϩάʹग़ͨ͠ΓͳͲ ☺
  44. 5S Z ܕ w 4VDDFTT W ͱ'BJMVSF F ͱ͍͏छྨ w

    4VDDFTT W ʹ੒ޭ࣌ͷ஋ w 'BJMVSF F ʹࣦഊ࣌ͷ৘ใ w ྫ֎͕౤͛ΒΕΔ͔΋͠Εͳ͍ॲཧΛ5SZͰғΉ͚ͩͰ0, w 5SZܕˠʮࣦഊ͢ΔՄೳੑ͕͋Δʯͱ͍͏ϝοηʔδ
  45. 5S Z Ͱ ੒ ޭ  ࣦ ഊ Λ ද

    ݱ ͢ Δ 1 // ݁ՌΛTryͰड͚औΔ 2 import scala.util.Try 3 def detect(bytes: Array[Byte]): Try[Charset] = { 4 val detectedCharsetName: String = ... 5 Try(Charset.forName(ud.getDetectedCharset)) 6 } 7 ࣦഊ͢Δ͔΋͠Εͳ͍ॲཧΛ5SZ ͰแΉ
  46. 5S Z Ͱ ੒ ޭ  ࣦ ഊ Λ ද

    ݱ ͢ Δ 1 // 2 val charset = detect(bytes) match { 3 case Success(charset) => charset 4 case Failure(e) => 5 logger.error(s"Oops! :$e") 6 Charset.defaultCharset 7 } ݺͿଆͰͷѻ͍ 4VDDFTT'BJMVSFͰύλʔϯϚον ☺
  47. ' B J M V S F ʹ ͳ Δ

    ͷ ͸ / P O ' B U B M ͳ ΋ ͷ • VirtualMachineError • ThreadDeath • InterruptedException • LinkageError • ControlThrowable 'BUBMͳΤϥʔɾྫ֎͸ͦͷ··εϩʔ͞ΕΔ
  48. 5S Z ͱ G P S ࣜ 1 // ྫ֎Λى͔͜͢΋͠Εͳ͍ϝιου

    2 def someMethod: Int = ??? 3 def anotherMethod: Int = ???
  49. 5S Z ͱ G P S ࣜ 1 // TryΛforࣜͰ߹੒͢Δ

    2 val result = for { 3 result1 <- Try(someMethod) 4 result2 <- Try(anotherMethod) 5 } yield result1 + result2 6 7 result match { 8 case Success(result) => println(result) 9 case Failure(e) => println(s"Opps: ", e) 10 }
  50. 5S Z ͱ G P S ࣜ 1 // TryΛforࣜͰ߹੒͢Δ

    2 val result = for { 3 result1 <- Try(someMethod) 4 result2 <- Try(anotherMethod) 5 } yield result1 + result2 6 7 result match { 8 case Success(result) => println(result) 9 case Failure(e) => println(s"Opps: ", e) 10 } ʮ"ͱ#͕྆ํ੒ޭͨ͠ͱ͖ͷΈ9͢Δʯ
 ͳͲ͕෼͔Γ΍͘͢දݱͰ͖Δ ☺
  51. D B T F  D M B T T

    ʹ ੍ ໿ Λ ࣋ ͨ ͤ Δ
  52. Ұ ݟ ͳ Μ ͷ ม ఩ ΋ ͳ ͍

    D B T F  D M B T T 1 case class Person( 2 name: String, 3 age: Int 4 )
  53. Ұ ݟ ͳ Μ ͷ ม ఩ ΋ ͳ ͍

    D B T F  D M B T T 1 case class Person( 2 name: String, 3 age: Int 4 ) ࡀͱ͔͸ͳ͍ΑͶɻ
 Ҿ਺ΛνΣοΫ͠ͳ͖Όɻ
  54. 1 case class Person( 2 name: String, 3 age: Int

    4 ) { 5 if(age < 0) throw new IllegalArgumentException("Age must be natural!") 6 } ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F  D M B T T
  55. 1 case class Person( 2 name: String, 3 age: Int

    4 ) { 5 if(age < 0) throw new IllegalArgumentException("Age must be natural!") 6 } ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F  D M B T T ࣄલ৚݅Ͱ͋Δ͜ͱΛ
 ΋ͬͱ໌֬ʹ఻͍͑ͨ
  56. 1 case class Person( 2 name: String, 3 age: Int

    4 ) { 5 require(age >= 0, "Age must be natural number!") 6 } ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F  D M B T T
  57. 1 case class Person( 2 name: String, 3 age: Int

    4 ) { 5 require(age >= 0, "Age must be natural number!") 6 } ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F  D M B T T ࣄલ৚݅
  58. 1 case class Person( 2 name: String, 3 age: Int

    4 ) { 5 require(age >= 0, "Age must be natural number!") 6 } ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F  D M B T T ࣄલ৚݅Λຬͨ͞ͳ͍৔߹ͷ
 Τϥʔϝοηʔδ
  59. 1 case class Person( 2 name: String, 3 age: Int

    4 ) { 5 require(age >= 0, "Age must be natural number!") 6 } ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F  D M B T T 1 val joe = Person("Joe Cool", -2))
  60. 1 case class Person( 2 name: String, 3 age: Int

    4 ) { 5 require(age >= 0, "Age must be natural number!") 6 } ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F  D M B T T 1 val joe = Person("Joe Cool", -2)) 2 // => java.lang.IllegalArgumentException: requirement failed: Age must be natural number!
  61. 1 case class Person( 2 name: String, 3 age: Int

    4 ) { 5 require(age >= 0, "Age must be natural number!") 6 } ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F  D M B T T &JUIFS΍5SZͱ૊Έ߹ΘͤΔͱ͏Ε͍͠ ☺ 1 val joe = Person("Joe Cool", -2)) 2 // => java.lang.IllegalArgumentException: requirement failed: Age must be natural number!
  62. T F B M F E  U S B

    J U Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ
  63. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ

    Ϛ ο ν 1 case class User(name: String, age: Int)
  64. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ

    Ϛ ο ν 1 case class User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan // ແྉϓϥϯ 5 case class Premium(user: User) extends Plan // ϓϨϛΞϜϓϥϯ
  65. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ

    Ϛ ο ν 1 case class User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan // ແྉϓϥϯ 5 case class Premium(user: User) extends Plan // ϓϨϛΞϜϓϥϯ 6 7 val userA = Free(User("Taro", 23)) 8 val userB = Premium(User("Jiro", 25)) 9
  66. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ

    Ϛ ο ν 1 case class User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan // ແྉϓϥϯ 5 case class Premium(user: User) extends Plan // ϓϨϛΞϜϓϥϯ 6 7 val userA = Free(User("Taro", 23)) 8 val userB = Premium(User("Jiro", 25)) 9 10 userB match { 11 case Free(User(name, _)) => println(s"Hi, $name.") 12 case Premium(User(name, _)) => println(s"Hello, $name!") 13 }
  67. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ

    Ϛ ο ν 1 case class User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan // ແྉϓϥϯ 5 case class Premium(user: User) extends Plan // ϓϨϛΞϜϓϥϯ 6 7 val userA = Free(User("Taro", 23)) 8 val userB = Premium(User("Jiro", 25)) 9 10 userB match { 11 case Free(User(name, _)) => println(s"Hi, $name.") 12 case Premium(User(name, _)) => println(s"Hello, $name!") 13 } 14 // => Hello, Jiro!
  68. ϓ ϥ ϯ Λ ૿ ΍ ͢ 1 case class

    User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan 5 case class Premium(user: User) extends Plan
  69. ϓ ϥ ϯ Λ ૿ ΍ ͢ 1 case class

    User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan 5 case class Premium(user: User) extends Plan 6 case class Campaign(user: User) extends Plan 7 8 val userA = Free(User("Taro", 23)) 9 val userB = Premium(User("Jiro", 25)) 10 val userC = Campaign(User("Saburo", 28))
  70. ϓ ϥ ϯ Λ ૿ ΍ ͢ 1 case class

    User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan 5 case class Premium(user: User) extends Plan 6 case class Campaign(user: User) extends Plan 7 8 val userA = Free(User("Taro", 23)) 9 val userB = Premium(User("Jiro", 25)) 10 val userC = Campaign(User("Saburo", 28)) 11 12 Seq(userA, userB, userC) foreach { 13 case Free(User(name, _)) => println(s"Hi, $name.") 14 case Premium(User(name, _)) => println(s"Hello, $name!") 15 }
  71. ϓ ϥ ϯ Λ ૿ ΍ ͢ 1 case class

    User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan 5 case class Premium(user: User) extends Plan 6 case class Campaign(user: User) extends Plan 7 8 val userA = Free(User("Taro", 23)) 9 val userB = Premium(User("Jiro", 25)) 10 val userC = Campaign(User("Saburo", 28)) 11 12 Seq(userA, userB, userC) foreach { 13 case Free(User(name, _)) => println(s"Hi, $name.") 14 case Premium(User(name, _)) => println(s"Hello, $name!") 15 } 16 // => Hi, Taro. 17 // => Hello, Jiro! 18 // => scala.MatchError: Campaign(User(Saburo,28)) …
  72. ϓ ϥ ϯ Λ ૿ ΍ ͢ 1 case class

    User(name: String, age: Int) 2 3 trait Plan 4 case class Free(user: User) extends Plan 5 case class Premium(user: User) extends Plan 6 case class Campaign(user: User) extends Plan 7 8 val userA = Free(User("Taro", 23)) 9 val userB = Premium(User("Jiro", 25)) 10 val userC = Campaign(User("Saburo", 28)) 11 12 Seq(userA, userB, userC) foreach { 13 case Free(User(name, _)) => println(s"Hi, $name.") 14 case Premium(User(name, _)) => println(s"Hello, $name!") 15 } 16 // => Hi, Taro. 17 // => Hello, Jiro! 18 // => scala.MatchError: Campaign(User(Saburo,28)) … .BUDI&SSPS͸࣮ߦ࣌Τϥʔɻ
 ࣮ߦલʹύλʔϯͷ࿙Εʹؾ͖͍ͮͨ
  73. 4 F B M F E म ০ ࢠ Ͱ

    ໢ ཏ ੑ Λ ୲ อ ͢ Δ 1 case class User(name: String, age: Int) 2 3 trait Plan
  74. 4 F B M F E म ০ ࢠ Ͱ

    ໢ ཏ ੑ Λ ୲ อ ͢ Δ 1 case class User(name: String, age: Int) 2 3 sealed trait Plan
  75. 4 F B M F E म ০ ࢠ Ͱ

    ໢ ཏ ੑ Λ ୲ อ ͢ Δ 1 case class User(name: String, age: Int) 2 3 sealed trait Plan w ಉ͡ϑΝΠϧ಺Ͱ͸ܧঝՄೳ w ผͷϑΝΠϧ͔Β͸ܧঝෆՄ
  76. 4 F B M F E म ০ ࢠ Ͱ

    ໢ ཏ ੑ Λ ୲ อ ͢ Δ 1 case class User(name: String, age: Int) 2 3 sealed trait Plan w ಉ͡ϑΝΠϧ಺Ͱ͸ܧঝՄೳ w ผͷϑΝΠϧ͔Β͸ܧঝෆՄ ͜ͷϑΝΠϧ಺Ͱఆٛ͞Εͨ΋ͷҎ֎ʹ
 1MBO͸ଘࡏ͠ͳ͍͜ͱ͕อূ͞ΕΔ
  77. 4 F B M F E म ০ ࢠ Ͱ

    ໢ ཏ ੑ Λ ୲ อ ͢ Δ 1 case class User(name: String, age: Int) 2 3 sealed trait Plan 4 case class Free(user: User) extends Plan 5 case class Premium(user: User) extends Plan 6 case class Campaign(user: User) extends Plan 7 8 val userA = Free(User("Taro", 23)) 9 val userB = Premium(User("Jiro", 25)) 10 val userC = Campaign(User("Saburo", 28)) 11 12 Seq(userA, userB, userC) foreach { 13 case Free(User(name, _)) => println(s"Hi, $name.") 14 case Premium(User(name, _)) => println(s"Hello, $name!") 15 }
  78. [warn] It would fail on the following input: Campaign(_) [warn]

    Seq(userA, userB, userC) foreach { [warn] ^ [warn] one warning found 4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ ίϯύΠϧ͢Δͱʜ ʮ$BNQBJHO͕དྷͨΒམͪΔ΍Ͱʂʯͱ ίϯύΠϥ͕ڭ͑ͯ͘ΕΔ ☺
  79. [warn] It would fail on the following input: Campaign(_) [warn]

    Seq(userA, userB, userC) foreach { [warn] ^ [warn] one warning found 4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ ίϯύΠϧ͢Δͱʜ ʮ$BNQBJHO͕དྷͨΒམͪΔ΍Ͱʂʯͱ ίϯύΠϥ͕ڭ͑ͯ͘ΕΔ ☺ 8BSOJOHແࢹ͠ͳ͍ͰͶ ☺
  80. ͓ ࿩ ͠ ͠ ͨ ͜ ͱ w ͳͥ#FUUFS+BWBͷઌͳͷ͔ʁ w

    ύλʔϯϚονͷύλʔϯ w λϓϧΛආ͚Δ w 4DBMBͳྫ֎ॲཧ w DBTFDMBTTʹ੍໿Λ࣋ͨͤΔ w TFBMFEUSBJUͰ໢ཏੑΛ୲อ͢Δ
  81. ) B W F  B  ( P P

    E  4 D B M B  - J G F  . : ✨