構造的差分ライブラリ開発時の悲劇・喜劇

151a0b14f5914e786e2e104cfb3a9b2f?s=47 Kuniwak
October 13, 2017

 構造的差分ライブラリ開発時の悲劇・喜劇

151a0b14f5914e786e2e104cfb3a9b2f?s=128

Kuniwak

October 13, 2017
Tweet

Transcript

  1. ߏ଄తࠩ෼ϥΠϒϥϦ
 ։ൃ࣌ͷ൵ܶتܶ σόοάΛॿ͚Δ

  2. ߏ଄తͳࠩ෼ͱ͸Կ͔ ·ͣ͸

  3. func testExample1() { let a = Example( key1: "I'm not

    changed", key2: "I'm deleted" ) let b = Example( key1: "I'm not changed", key2: "I'm inserted" ) XCTAssertEqual(a, b) } Α͋͘ΔTUSVDUͷൺֱ
  4. XCTAssertEqual failed: ("Example(key1: "I\'m not changed", key2: "I\'m deleted")") is

    not equal to ("Example(key1: "I\'m not changed", key2: "I\'m inserted")") - ςετ݁Ռ͸ඇৗʹΘ͔ΓͮΒ͍
  5. IUUQHJUIVCDPN,VOJXBL.JSSPS%J⒎,JU ͦ͜Ͱ

  6. import MirrorDiffKit func testExample2() { let a = Example( key1:

    "I'm not changed", key2: "I'm deleted" ) let b = Example( key1: "I'm not changed", key2: "I'm inserted" ) XCTAssertEqual(a, b, diff(between: a, and: b)) } ࣦഊ࣌ͷϝοηʔδʹ
 .JSSPS%J⒎,JUͷEJ⒎Λࢦఆ .JSSPS%J⒎,JUΛJNQPSU
  7. struct Example { key1: "I'm not changed" - key2: "I'm

    deleted" + key2: "I'm inserted" } ͜Ε͕ߏ଄తͳࠩ෼ ͙͢ʹࠩҟ͕Θ͔Γ·͢
  8. [ "I'm not changed" "I'm not changed" - "I'm deleted"

    "I'm not changed" + "I'm inserted" ] ഑ྻͷॱংมߋͳͲ΋
 ߏ଄తͳࠩ෼Ͱ͢ ͜Ε΋ݟ΍͘͢දࣔ͞Ε·͢
  9. IUUQHJUIVCDPN,VOJXBL.JSSPS%J⒎,JU ΑΖ͓͘͠ئ͍͠·͢

  10. ࢓૊Έͷղઆ ࠩ෼ܭࢉͷ

  11. let example = Example( key1: "I'm not changed", key2: "I'm

    deleted" ) let hint = ( subject: Example.self, displayStyle: .struct, children: [ (label: "key1", value: "I'm not changed"), (label: "key2", value: "I'm deleted"), ] ) ߏ଄తͳࠩ෼ͷܭࢉʹ͸ɺ
 ࣍ͷΑ͏ͳΦϒδΣΫτͷ
 ߏ଄ͷώϯτ͕ෆՄܽͰ͢ ΦϒδΣΫτͷܕ ΦϒδΣΫτͷछྨ ϓϩύςΟͷ໊લͱ஋
  12. ͦͷػೳΛ୲͏ͷ͕.JSSPS
 ʢඪ४ϥΠϒϥϦͷ"1*Ͱ͢ʣ

  13. let example = Example( key1: "I'm not changed", key2: "I'm

    deleted" ) let mirror = Mirror(reflecting: example) let hint = ( subject: mirror.subjectType, displayStyle: mirror.displayStyle, children: mirror.children ) ௐ΂͍ͨΦϒδΣΫτ͔Β
 .JSSPSΦϒδΣΫτΛ
 ࡞੒͢Δͱɺ ܕ৘ใ΍ΦϒδΣΫτͷछྨɺ
 ϓϩύςΟͷ໊લͱ஋ͳͲΛ
 ೖखͰ͖·͢
  14. .JSSPS%J⒎,JU͸ɺ
 ͜ͷ.JSSPSΛ࢖ͬͯ
 ࣮ݱ͞Ε͍ͯ·͢

  15. ͍ΖΜͳ͜ͱ͕Ͱ͖ͦ͏Ͱ
 ເͷ޿͕Δ"1*Ͱ͢Ͷ

  16. تܶ͸͜͜·Ͱͩ

  17. ΍͹͍OJM͕΍͹͍໰୊ ൵ܶͦͷ

  18. struct Example { let any: Any? } let example =

    Example(any: nil) if let first = Mirror(reflecting: example) .children.first { print(first.value) } ϓϩύςΟΛOJMͰॳظԽ ϓϩύςΟͷ஋ΛݟΔͱɺ
 ઌ΄ͲOJMͰॳظԽͨ͠ͷͰ
 OJMʹͳ͍ͬͯΔ "OZ ͷϓϩύςΟ͕͋ΔTUSVDU .JSSPSΛ࡞੒ͯ͠ɺTUSVDUͷ
 ϓϩύςΟͷώϯτΛೖख
  19. struct Example { let any: Any? } let example =

    Example(any: nil) if let first = Mirror(reflecting: example) .children.first { print(first.value == nil) print(first.value) } GBMTF OJMͰ΋͔֬ΊͯΈΑ͏  ͔͠͠ೖ͍ͬͯΔͷ͸OJMʜ
  20. ߟ࡯ฤ ൵͠Έͷ

  21. "OZʹ͸
 ͳΜͰ΋ೖΔ ᶃ Int String Bool Any

  22. 0QUJPOBM΋
 ೖΕΒΕΔ ᶄ Optional<T> Any

  23. ͢ΔͱOJM΋
 ೖΓ͏Δ ᶄ nil Any

  24.  ᶄ nil Any == nil GBMTF

  25. let x: Any? = nil let wrapper: Any = x

    // WARNING: Comparing non-optional value of // type 'Any' to nil always returns false print(x == nil) ࣮͸ղઆͨ͠ྫΛίʔυʹ͢Δͱܯࠂ͕ग़Δ ʮ0QUJPOBM͡Όͳ͍஋ͱOJMΛ
 ɹൺֱͯ͠΋ৗʹGBMTFͩΑʯ 
  26. ͭ·Γɺ"OZʹOJMΛ
 ೖΕͯ͸ͳΒͳ͍ͷͰ͢

  27. ͔͠͠ɺ.JSSPSͰऔಘͨ͠
 ϓϩύςΟͷ஋ͷܕ͸
 ໰౴ແ༻Ͱ"OZͱ͍͏൵͠Έ ͳͷͰɺϓϩύςΟʹOJMΛ΋ͭ
 ΦϒδΣΫτΛ.JSSPSʹ͔͚Δͱ
 Ϋϥογϡͷةݥ͕͋Γ·͢

  28. .JSSPS%J⒎,JUͰ͸͜ͷ໰୊ʹ
 ରॲ͍ͯ͠·͢ͷͰ҆͝৺Λʜ

  29. ཁૉ਺ͷUVQMF໰୊ ൵ܶͦͷ

  30. enum Example { case zero case one(key: String) case two(key1:

    String, key2: String) } 4XJGUͰ͸FOVNͷDBTFʹ෇ଐ͢Δ஋ΛఆٛͰ͖·͢ ͜ͷ෇ଐ͢Δ஋͸BTTPDJBUFEWBMVFTͱݺ͹Ε͍ͯ·͢
  31. enum Example { case one(key: String) case two(key1: String, key2:

    String) } func test() { let x1: Example = .one(key: "value") let x2: Example = .two(key1: "value1", key2: "value2") let mirror1 = Mirror(reflecting: x1) let mirror2 = Mirror(reflecting: x2) dump(mirror1.children.first!.value) dump(mirror2.children.first!.value) } ͦΕͧΕΛ.JSSPSʹ͔͚·͢ ͜͜Ͱ͸BTTPDJBUFEWBMVFTͷ
 ཁૉ਺͕ҟͳΔͭͷDBTFΛ
 ఆٛ͠·͢ BTTPDJBUFWBMVFT͸ɺ
 TUSVDUͷϓϩύςΟͱ
 ಉ͡Α͏ʹDIJMESFOͰ
 දݱ͞Ε·͢ ͦΕͧΕͷDIJMESFOΛ
 ֬ೝͯ͠Έ·͠ΐ͏
  32. enum Example { case one(key: String) case two(key1: String, key2:

    String) } func test() { let x1: Example = .one(key: "value") let x2: Example = .two(key1: "value1", key2: "value2") let mirror1 = Mirror(reflecting: x1) let mirror2 = Mirror(reflecting: x2) dump(mirror1.children.first!.value) dump(mirror2.children.first!.value) } BTTPDJBUFEWBMVFT͕
 ͭͷ৔߹ WBMVF ͭͷ৔߹
  
 LFZWBMVF 
 LFZWBMVF
  ܕ͕ҧ͏ 
  33. ߟ࡯ฤ ൵͠Έͷ

  34. let y: Any = (number: 123) print(type(of: y)) ܕΛௐ΂ͯΈΔͱ
 

    *OU ຊ౰͸BTTPDJBUFEWBMVFTͷཁૉ਺͕
 ͍ͭ͘Ͱ͋ΕɺDIJMESFOͷܕ͸UVQMFʹ
 ͔ͨͬͨ͠ͷͰ͸ͱਪଌ ͔͠͠ɺཁૉ਺ͷ͚࣌ͩࣄ৘͕͋ͬͯ
 UVQMFʹͰ͖ͳ͔͔ͬͨ΋͠Εͳ͍ͷͰɺ
 ࢼ͠ʹཁૉ͕ͭͷUVQMFΛ࡞੒ͯ͠ΈΔ UVQMFͰ͸ͳ͍ 
  35. // Error: cannot create a single-element tuple with // an

    element label let x: (number: Int) = (number: 123)
 
 let y: Any = (number: 123) print(type(of: y)) // Int ࣮͸ɺ4XJGUͷܕͰ͸ཁૉ͕ͭͷUVQMF͸ఆٛͰ͖ͳ͍ ͔͠͠ɺཁૉ਺ͷUVQMFܕ͕
 ࡞Εͳ͍͚ͩͳͷͰɺܕΛ
 "OZʹͯ͠͠·͑͹ཁૉ਺ͷ
 UVQMFΒ͖͠΋ͷΛఆٛͰ͖Δ ͔͠͠ɺఆٛͰ͖ͨͱͯ͠΋ɺ
 ͦͷܕ͸ཁૉͷத਎ͷܕʹ
 ͳΔΑ͏ͩ ͭ·Γɺཁૉ਺ͷUVQMF͸
 ଘࡏͰ͖ͳ͍͜ͱ͕Θ͔Δ
  36. ཁૉ਺ͷUVQMFܕ͸ଘࡏͰ͖ͳ͍ͷͰɺ
 ຊདྷ͸UVQMFͰ͋Δ͸ͣͷ
 BTTPDJBUFEWBMVFT͕ɺཁૉ਺ͷ
 ͱ͖ʹத਎͚ͩʹͳΔͷͰͨ͠ʜ

  37. .JSSPS%J⒎,JUͰ͸͜ͷ໰୊ʹ
 ରॲ͍ͯ͠·͢ͷͰ҆͝৺Λʜ

  38. ΧδϡΞϧʹյΕΔ ൵ܶͦͷ

  39. ·ͱΊ w .JSSPSͱ͍͏TUSVDUͳͲͷߏ଄Λ
 ௐ΂ΔͨΊͷ"1*͕͋Γ·͢ w ৭ʑͰ͖ͦ͏Ͱເ͕޿͕Γ·͢ w ͔͠͠ɺ͔ͳΓͷͭΒΈ͕͋Γ·͢ͷͰ
 ΍͍ͬͯ͘ࡍʹ͸.JSSPS%J⒎,JUͷ
 ճආྫΛࢀߟʹ͢ΔͱΑ͍Ͱ͠ΐ͏