Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
構造的差分ライブラリ開発時の悲劇・喜劇
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Kuniwak
PRO
October 13, 2017
Programming
3.2k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
構造的差分ライブラリ開発時の悲劇・喜劇
https://iosdc-reject-conference.connpass.com/event/64175/
Kuniwak
PRO
October 13, 2017
More Decks by Kuniwak
See All by Kuniwak
AIベース静的検査器の偽陽性率を抑える工夫3選
orgachem
PRO
8
3k
仕様漏れ実装漏れをなくすトレーサビリティAI基盤のご紹介
orgachem
PRO
16
11k
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
40
24k
DeNA での思い出 / Memories at DeNA
orgachem
PRO
8
3.7k
それ CLI フレームワークがなくてもできるよ / Building CLI Tools Without Frameworks
orgachem
PRO
18
4.8k
状態遷移図を書こう / Sequence Chart vs State Diagram
orgachem
PRO
4
820
テストケースの名前はどうつけるべきか?
orgachem
PRO
2
1k
欠陥を早期に発見するための Software Engineer in Test とその重要性 / What is Software Engineer in Test and How they works
orgachem
PRO
22
5.1k
住宅を WebXR で評価しよう / Evaluating My Home by WebXR
orgachem
PRO
0
260
Other Decks in Programming
See All in Programming
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
4.8k
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
440
Family mrubyの進捗
kishima
1
130
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
130
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
470
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
310
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
200
AI活用は、個人から組織へ|マルチプレイヤーエージェントハーネス「QM」の社内活用事例 / AI use is moving from individuals to orgs
rkaga
1
120
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.1k
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
1
150
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
180
iOSDC2026登壇資料.pdf
riofujimon
0
170
Featured
See All Featured
Accessibility Awareness
sabderemane
1
210
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
330
Designing for Performance
lara
611
70k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Exploring anti-patterns in Rails
aemeredith
4
510
Building the Perfect Custom Keyboard
takai
2
880
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
510
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
280
The Mindset for Success: Future Career Progression
greggifford
PRO
0
500
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ͷ ճආྫΛࢀߟʹ͢ΔͱΑ͍Ͱ͠ΐ͏