Trait in Scala

Trait in Scala

2014/05/09 Livesense SICP倶楽部LT大会にて
ScalaのTraitについての解説

E60aa4f80303f3f386898546ddb3686a?s=128

Livesense Inc.

May 15, 2014
Tweet

Transcript

  1. 5SBJUJO4DBMB  -JWFTFOTF4*$1۞ָ෦-5େձ ౡ઒༔ଠ

  2. 4DBMB

  3. CMPHFOGSBODIJTFENJOEDPNTDBMBOPUGVODUJPOBM

  4. 4DBMB

  5. +BWB

  6. w JOUFSGBDFͷσϑΥϧτ࣮૷ w ϥϜμࣜ w ߴ֊ؔ਺ w ܕਪ࿦ͷڧԽ w ฒྻੑͷڧԽʢฒྻίϨΫγϣϯɺ$PNQMFUF'VUVSFʣ

    w ஗ԆධՁ w 4USFBN w 0QUJPOBM w FUD IUUQXXXJOGPRDPNKQBSUJDMFTKBWBWTTDBMB IUUQOFXTNZOBWJKQTQFDJBMKBWB
  7. ͦΕͰ΋4DBMB Λ࢖͍͍͔ͨʁ

  8. ͜Μͳࢿྉ࡞Δ͘Β͍ ͔ͩΒΘ͔Γ·͢ΑͶʁ

  9. ຊ೔ͷςʔϚ ʰτϨΠτʱ

  10. ͳͥτϨΠτΛ ͱΓ͋͛Δ͔ʁ

  11. w τϨΠτ͸4DBMBͷΦϒδΣΫτࢦ޲ݴޠͱ ͯ͠ͷϋΠϥΠτͷҰͭͩͱࢥ͏ɻ w "DUPS΍Β'VUVSF΍ΒΛ࢖ͬͨฒߦੑ੍ޚ ͷར఺͸ଟ͍͚Ͳɺଟ͘ͷ৬ۀϓϩάϥϚ͕ ௚໘͢Δ՝୊͸ɺ001Λ࢖ͬͨιϑτ΢ΣΞ ՝୊ͷղܾʹ͋ΔͷͰ͸ͳ͍͔ͱࢥ͏ɻ w ͱ͍͏͜ͱͰɺ4DBMBͷݴޠ঺հͱͯ͠τϨ

    Πτ͔ΒऔΓ্͛ͯΈΔɻ
  12. $ scala scala> “trait”.translate(“ja_JP”) res0: List[String] = List(ಛੑ, ಛ௃, ಛ৭)

    IUUQFKKFXFCMJPKQDPOUFOUUSBJU
  13. τϨΠτͱ͸ʁ

  14. ΫϥεͷΑ͏ʹɺϝιουͱϑΟʔ ϧυͷఆٛΛΧϓηϧԽͨ͠΋ͷ Ͱɺ4DBMBʹ͓͚Δίʔυ࠶ར ༻ͷجຊ୯ҐʢίοϓຊΑΓʣ

  15. trait Philosophical { def philosophize() { println(“զࢥ͏ނʹզ͋Γ”) } }

  16. ΫϥεʹϛοΫεΠϯ w ந৅ϝϯόʔ͚ͩΛએݴͯ͠ɺϛοΫεΠϯ͢Δ ΫϥεͰͷ࣮૷Λڧ੍ w ࣮૷Λఆٛ͢Δ͜ͱ΋Ͱ͖Δ w ෳ਺ͷτϨΠτΛಉ࣌ʹϛοΫεΠϯ͢Δ͜ͱ΋ Ͱ͖Δ w

    ϛοΫεΠϯͨ͠ϝιουΛΦʔόʔϥΠυͨ͠ ΓɺTVQFSݺͼग़͢͠Δ͜ͱ΋Ͱ͖Δ
  17. trait A { def f() // ந৅ϝιου } ! trait

    B { def foo() = println("foo") } ! trait C { def bar() = println("bar") } ! class D extends A with B with C { def f() = foo() // ந৅ϝιουΛ࣮૷ˍτϨΠτBͷfooΛݺͼग़͠ override def bar() = { // τϨΠτCͷbarϝιουΛoverride super.bar() // τϨΠτCͷbarϝιουΛݺͼग़͠ println("BAR") } }
  18. Πϯελϯεੜ੒࣌ʹ ϛοΫεΠϯ

  19. class Japanese ! trait Kansai ! trait Kanto ! val

    me = new Japanese with Kansai with Kanto
  20. TVQFSݺͼग़͠ͷઢܗԽ

  21. class Animal ! trait HasLegs extends Animal ! trait FourLegged

    extends HasLegs ! trait Furry extends Animal ! class Cat extends Animal with Furry with FourLegged
  22. "OJNBM )BT-FHT 'VSSZ 'PVS-FHHFE $BU DMBTT$BUFYUFOET"OJNBM XJUI'VSSZXJUI'PVS-FHHFE $BU'PVS-FHHFE )BT-FHHFE'VSSZ"OJNBM ઢܗԽ

  23. ੵΈॏͶՄೳͳมߋ

  24. abstract class IntQueue { def put(x: Int) def get(): Int

    } ! import scala.collection.mutable.ArrayBuffer class BasicIntQueue { private val but = new ArrayBuffer[Int] def put(x: Int) = but += x def get() = but.remove(0) } ! trait Doubling extends IntQueue { abstract override def put(x: Int) = { super.put(2 * x) } } ! trait Filtering extends IntQueue { abstract override def put(x: Int) = { super.put(x.abs) } }
  25. val q1 = new BasicIntQueue q1.put(10) q1.get() // Int =

    10 ! val q2 = new BasicIntQueue with Doubling q2.put(10) q2.get() // Int = 20 ! val q3 = new BasicIntQueue with Doubling with Filtering q3.put(-10) q3.get() // Int = 20 ʰ4DBMBεέʔϥϒϧϓϩάϥϛϯάʱষΑΓ
  26. "01ͬΆ͍͜ͱ΋Մೳ ࢀߟ IUUQEIBUFOBOFKQKJLP

  27. trait Executor { def execute(): Unit } ! trait LoggableExecutor

    extends Executor { def log(() => Unit):Unit = … abstract override def execute(): Unit { log { super.execute } } } ! class SomeExecutor extends Executor { def execute(): Unit = … } ! val e = new SomeExecutor with LoggableExecutor e.execute
  28. ࣗ෼ܕΞϊςʔγϣϯ

  29. trait A { def foo() = “foo” } ! trait

    B { def bar() = “bar” } ! trait C { this: A with B => def f() = foo + bar } ! val c = new C with A with B c.f // String = foobar
  30. 5SBJU$ͷΠϯελϯεΛੜ੒͢ Δʹ͸"ͱ#ΛϛοΫεΠϯ͠ͳ ͚Ε͹ͳΒͳ͍ɻ$͔Β"ͱ#΁ ͷґଘੑΛ໌ࣔ͢Δ͜ͱ͕Ͱ͖Δɻ

  31. $BLF1BUUFSOͰ%*

  32. class User ! trait UserRepositoryComponent { val repos: UserRepository trait

    UserRepository { def findById(id: Int): User } } ! class UserService { this: UserRepositoryComponent => def findById(id: Int): User = { repos.findById(id) } }
  33. trait MySQLUserRepositoryComponent extends UserRepository Component { val repos = new

    MySQLUserRepository class MySQLUserRepository = { def findById(id: Int): User = … } } ! val userService = new UserService with MySQLUserRepositoryComponent ! val user = userService.findById(1)
  34. ஫ʣDBLFQBUUFSO ʹ͍ͭͯ͸໰୊఺΋ࢦఠ ͞Ε͍ͯΔͷͰ஫ҙ

  35. IUUQUPHFUUFSDPNMJ

  36. ·ͱΊ

  37. τϨΠτ࢖͏ͱ001͕ؾ ࣋ͪΑ͘ͳΔɻ͔΋Ͷɻ