Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
構造的差分ライブラリ開発時の悲劇・喜劇
Search
Kuniwak
PRO
October 13, 2017
Programming
7
3k
構造的差分ライブラリ開発時の悲劇・喜劇
https://iosdc-reject-conference.connpass.com/event/64175/
Kuniwak
PRO
October 13, 2017
Tweet
Share
More Decks by Kuniwak
See All by Kuniwak
DeNA での思い出 / Memories at DeNA
orgachem
PRO
6
2.5k
それ CLI フレームワークがなくてもできるよ / Building CLI Tools Without Frameworks
orgachem
PRO
18
4.2k
状態遷移図を書こう / Sequence Chart vs State Diagram
orgachem
PRO
4
430
テストケースの名前はどうつけるべきか?
orgachem
PRO
2
620
欠陥を早期に発見するための Software Engineer in Test とその重要性 / What is Software Engineer in Test and How they works
orgachem
PRO
21
4.5k
住宅を WebXR で評価しよう / Evaluating My Home by WebXR
orgachem
PRO
0
180
HOME VR
orgachem
PRO
1
820
uGUI の自動操作の考え方と操作方法
orgachem
PRO
1
1.5k
Swift Macro に備えて構文木を 10min で学ぶ / Learn Syntax Tree for Swift Macro in 10 minutes
orgachem
PRO
1
1.5k
Other Decks in Programming
See All in Programming
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
110
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
2
450
猫と暮らすネットワークカメラ生活🐈 ~Vision frameworkでペットを愛でよう~ / iOSDC Japan 2025
yutailang0119
0
220
ABEMAモバイルアプリが Kotlin Multiplatformと歩んだ5年 ─ 導入と運用、成功と課題 / iOSDC 2025
akkyie
0
320
ててべんす独演会〜Flowの全てを語ります〜
tbsten
1
220
CSC305 Lecture 01
javiergs
PRO
1
400
Introducing ReActionView: A new ActionView-Compatible ERB Engine @ Kaigi on Rails 2025, Tokyo, Japan
marcoroth
3
910
デミカツ切り抜きで面倒くさいことはPythonにやらせよう
aokswork3
0
180
プログラミングどうやる? ~テスト駆動開発から学ぶ達人の型~
a_okui
0
190
大規模アプリのDIフレームワーク刷新戦略 ~過去最大規模の並行開発を止めずにアプリ全体に導入するまで~
mot_techtalk
0
380
詳しくない分野でのVibe Codingで困ったことと学び/vibe-coding-in-unfamiliar-area
shibayu36
3
4.3k
Advance Your Career with Open Source
ivargrimstad
0
320
Featured
See All Featured
A designer walks into a library…
pauljervisheath
209
24k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.5k
Typedesign – Prime Four
hannesfritz
42
2.8k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
A Modern Web Designer's Workflow
chriscoyier
697
190k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
2.6k
RailsConf 2023
tenderlove
30
1.2k
Why Our Code Smells
bkeepers
PRO
339
57k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
114
20k
A Tale of Four Properties
chriscoyier
160
23k
Transcript
ߏతࠩϥΠϒϥϦ ։ൃ࣌ͷ൵ܶتܶ σόοάΛॿ͚Δ
ߏతͳࠩͱԿ͔ ·ͣ
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ͷൺֱ
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")") - ςετ݁ՌඇৗʹΘ͔ΓͮΒ͍
IUUQHJUIVCDPN,VOJXBL.JSSPS%J⒎,JU ͦ͜Ͱ
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
struct Example { key1: "I'm not changed" - key2: "I'm
deleted" + key2: "I'm inserted" } ͜Ε͕ߏతͳࠩ ͙͢ʹࠩҟ͕Θ͔Γ·͢
[ "I'm not changed" "I'm not changed" - "I'm deleted"
"I'm not changed" + "I'm inserted" ] ྻͷॱংมߋͳͲ ߏతͳࠩͰ͢ ͜Εݟ͘͢දࣔ͞Ε·͢
IUUQHJUIVCDPN,VOJXBL.JSSPS%J⒎,JU ΑΖ͓͘͠ئ͍͠·͢
Έͷղઆ ࠩܭࢉͷ
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"), ] ) ߏతͳࠩͷܭࢉʹɺ ࣍ͷΑ͏ͳΦϒδΣΫτͷ ߏͷώϯτ͕ෆՄܽͰ͢ ΦϒδΣΫτͷܕ ΦϒδΣΫτͷछྨ ϓϩύςΟͷ໊લͱ
ͦͷػೳΛ୲͏ͷ͕.JSSPS ʢඪ४ϥΠϒϥϦͷ"1*Ͱ͢ʣ
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ΦϒδΣΫτΛ ࡞͢Δͱɺ ܕใΦϒδΣΫτͷछྨɺ ϓϩύςΟͷ໊લͱͳͲΛ ೖखͰ͖·͢
.JSSPS%J⒎,JUɺ ͜ͷ.JSSPSΛͬͯ ࣮ݱ͞Ε͍ͯ·͢
͍ΖΜͳ͜ͱ͕Ͱ͖ͦ͏Ͱ ເͷ͕Δ"1*Ͱ͢Ͷ
تܶ͜͜·Ͱͩ
͍OJM͕͍ ൵ܶͦͷ
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ͷ ϓϩύςΟͷώϯτΛೖख
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ʜ
ߟฤ ൵͠Έͷ
"OZʹ ͳΜͰೖΔ ᶃ Int String Bool Any
0QUJPOBM ೖΕΒΕΔ ᶄ Optional<T> Any
͢ΔͱOJM ೖΓ͏Δ ᶄ nil Any
ᶄ nil Any == nil GBMTF
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ͩΑʯ
ͭ·Γɺ"OZʹOJMΛ ೖΕͯͳΒͳ͍ͷͰ͢
͔͠͠ɺ.JSSPSͰऔಘͨ͠ ϓϩύςΟͷͷܕ ແ༻Ͱ"OZͱ͍͏൵͠Έ ͳͷͰɺϓϩύςΟʹOJMΛͭ ΦϒδΣΫτΛ.JSSPSʹ͔͚Δͱ Ϋϥογϡͷةݥ͕͋Γ·͢
.JSSPS%J⒎,JUͰ͜ͷʹ ରॲ͍ͯ͠·͢ͷͰ҆͝৺Λʜ
ཁૉͷUVQMF ൵ܶͦͷ
enum Example { case zero case one(key: String) case two(key1:
String, key2: String) } 4XJGUͰFOVNͷDBTFʹଐ͢ΔΛఆٛͰ͖·͢ ͜ͷଐ͢ΔBTTPDJBUFEWBMVFTͱݺΕ͍ͯ·͢
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Λ ֬ೝͯ͠Έ·͠ΐ͏
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 ܕ͕ҧ͏
ߟฤ ൵͠Έͷ
let y: Any = (number: 123) print(type(of: y)) ܕΛௐͯΈΔͱ
*OU ຊBTTPDJBUFEWBMVFTͷཁૉ͕ ͍ͭ͘Ͱ͋ΕɺDIJMESFOͷܕUVQMFʹ ͔ͨͬͨ͠ͷͰͱਪଌ ͔͠͠ɺཁૉͷ͚࣌ͩࣄ͕͋ͬͯ UVQMFʹͰ͖ͳ͔͔ͬͨ͠Εͳ͍ͷͰɺ ࢼ͠ʹཁૉ͕ͭͷUVQMFΛ࡞ͯ͠ΈΔ UVQMFͰͳ͍
// 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 ଘࡏͰ͖ͳ͍͜ͱ͕Θ͔Δ
ཁૉͷUVQMFܕଘࡏͰ͖ͳ͍ͷͰɺ ຊདྷUVQMFͰ͋Δͣͷ BTTPDJBUFEWBMVFT͕ɺཁૉͷ ͱ͖ʹத͚ͩʹͳΔͷͰͨ͠ʜ
.JSSPS%J⒎,JUͰ͜ͷʹ ରॲ͍ͯ͠·͢ͷͰ҆͝৺Λʜ
ΧδϡΞϧʹյΕΔ ൵ܶͦͷ
·ͱΊ w .JSSPSͱ͍͏TUSVDUͳͲͷߏΛ ௐΔͨΊͷ"1*͕͋Γ·͢ w ৭ʑͰ͖ͦ͏Ͱເ͕͕Γ·͢ w ͔͠͠ɺ͔ͳΓͷͭΒΈ͕͋Γ·͢ͷͰ ͍ͬͯ͘ࡍʹ.JSSPS%J⒎,JUͷ ճආྫΛࢀߟʹ͢ΔͱΑ͍Ͱ͠ΐ͏