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
それ CLI フレームワークがなくてもできるよ / Building CLI Tools Without Frameworks
orgachem
PRO
17
3.7k
状態遷移図を書こう / Sequence Chart vs State Diagram
orgachem
PRO
4
330
テストケースの名前はどうつけるべきか?
orgachem
PRO
2
560
欠陥を早期に発見するための Software Engineer in Test とその重要性 / What is Software Engineer in Test and How they works
orgachem
PRO
21
4.4k
住宅を WebXR で評価しよう / Evaluating My Home by WebXR
orgachem
PRO
0
170
HOME VR
orgachem
PRO
1
810
uGUI の自動操作の考え方と操作方法
orgachem
PRO
1
1.5k
Swift Macro に備えて構文木を 10min で学ぶ / Learn Syntax Tree for Swift Macro in 10 minutes
orgachem
PRO
1
1.5k
SoftWare Engineer in Test のおしごと / What is SWET
orgachem
PRO
1
1.2k
Other Decks in Programming
See All in Programming
202507_ADKで始めるエージェント開発の基本 〜デモを通じて紹介〜(奥田りさ)The Basics of Agent Development with ADK — A Demo-Focused Introduction
risatube
PRO
6
1.4k
CLI ツールを Go ライブラリ として再実装する理由 / Why reimplement a CLI tool as a Go library
ktr_0731
3
990
管你要 trace 什麼、bpftrace 用下去就對了 — COSCUP 2025
shunghsiyu
0
300
MySQL9でベクトルカラム登場!PHP×AWSでのAI/類似検索はこう変わる
suguruooki
1
290
Constant integer division faster than compiler-generated code
herumi
2
440
Strands Agents で実現する名刺解析アーキテクチャ
omiya0555
1
110
STUNMESH-go: Wireguard NAT穿隧工具的源起與介紹
tjjh89017
0
110
GitHub Copilotの全体像と活用のヒント AI駆動開発の最初の一歩
74th
7
2.1k
대규모 트래픽을 처리하는 프론트 개발자의 전략
maryang
0
120
DynamoDBは怖くない!〜テーブル設計の勘所とテスト戦略〜
hyamazaki
0
190
React は次の10年を生き残れるか:3つのトレンドから考える
oukayuka
41
16k
Flutter로 Gemini와 MCP를 활용한 Agentic App 만들기 - 박제창 2025 I/O Extended Seoul
itsmedreamwalker
0
120
Featured
See All Featured
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Building Adaptive Systems
keathley
43
2.7k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
183
54k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Designing for humans not robots
tammielis
253
25k
Become a Pro
speakerdeck
PRO
29
5.5k
Typedesign – Prime Four
hannesfritz
42
2.7k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
283
13k
Agile that works and the tools we love
rasmusluckow
329
21k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
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ͷ ճආྫΛࢀߟʹ͢ΔͱΑ͍Ͱ͠ΐ͏