Slide 1

Slide 1 text

Patterns in Swift ishkawa

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Patterns in Swift i f - c a s e s w i t c h - c a s e f o r - c a s e l e t s o m e t h i n g = . . . i f c a s e l e t f o o a s F o o = s o m e t h i n g { . . . } d o - c a t c h d o { t r y d o S o m e t h i n g ( ) } c a t c h l e t e r r o r a s M y E r r o r { p r i n t ( e r r o r ) }

Slide 4

Slide 4 text

問題点 文法がよくわからん

Slide 5

Slide 5 text

例 1

Slide 6

Slide 6 text

enum の associated value e n u m E i t h e r < A , B > { c a s e L e f t ( A ) c a s e R i g h t ( B ) } l e t e i t h e r : E i t h e r < A , B > = . . . s w i t c h e i t h e r { c a s e . L e f t ( l e t a ) : p r i n t ( " A : \ ( a ) " ) c a s e . R i g h t ( l e t b ) : p r i n t ( " B : \ ( b ) " ) }

Slide 7

Slide 7 text

これでもいいの? e n u m E i t h e r < A , B > { c a s e L e f t ( A ) c a s e R i g h t ( B ) } l e t e i t h e r : E i t h e r < A , B > = . . . s w i t c h e i t h e r { c a s e l e t . L e f t ( a ) : p r i n t ( " A : \ ( a ) " ) c a s e l e t . R i g h t ( b ) : p r i n t ( " B : \ ( b ) " ) }

Slide 8

Slide 8 text

例 2

Slide 9

Slide 9 text

Optional l e t t u p l e : ( A ? , B ) = . . . s w i t c h t u p l e { c a s e ( . S o m e ( l e t a ) , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) c a s e ( . N o n e , l e t b ) : p r i n t ( " A : n i l , B : \ ( b ) " ) }

Slide 10

Slide 10 text

これでもいいの? l e t t u p l e : ( A ? , B ) = . . . s w i t c h t u p l e { c a s e ( l e t a ? , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) c a s e ( . N o n e , l e t b ) : p r i n t ( " A : n i l , B : \ ( b ) " ) }

Slide 11

Slide 11 text

これも同じ???? l e t t u p l e : ( A ? , B ) = . . . s w i t c h t u p l e { c a s e ( l e t a ? , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) c a s e ( l e t a , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) }

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

パターンの文法を知らないと ... 込み入った switch 文が読めない 愚直な switch 文しか書けない ググってみるけどよくわからなくて時間を浪費する 結果的に劣等感に悩まされる

Slide 14

Slide 14 text

パターンの文法はそんなに難しくないけど 初見で察することができるほど簡単ではない

Slide 15

Slide 15 text

あらためてパターンってなに? 具体的な値ではなく値の性質を表すもの 具体的な値がマッチしているかどうかテストできる 数種類のパターンがあり組み合わせが可能 Wildcard Pattern Identifier Pattern Value‑Binding Pattern Tuple Pattern Enumeration Case Pattern Optional Pattern Type‑Casting Pattern Expression Pattern

Slide 16

Slide 16 text

組み合わせ可能 l e t t u p l e : ( A ? , B ) = . . . s w i t c h t u p l e { c a s e ( l e t a ? , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) c a s e ( l e t a , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) } c a s e ( l e t a ? , l e t b ) では以下が組み合わされている Tuple Pattern Identifier Pattern Value‑Binding Pattern Optional Pattern

Slide 17

Slide 17 text

各パターンの仕様 書くのが大変なので公式を参照します The Swift Programming Language Language Reference Patterns

Slide 18

Slide 18 text

どれも結構使う

Slide 19

Slide 19 text

よくわからなかったやつを振り返ると ...

Slide 20

Slide 20 text

例 1: パターンの組み合わせの順序が異なる l e t e i t h e r : E i t h e r < A , B > = . . . s w i t c h e i t h e r { c a s e . L e f t ( l e t a ) : p r i n t ( " A : \ ( a ) " ) c a s e . R i g h t ( l e t b ) : p r i n t ( " B : \ ( b ) " ) } s w i t c h e i t h e r { c a s e l e t . L e f t ( a ) : p r i n t ( " A : \ ( a ) " ) c a s e l e t . R i g h t ( b ) : p r i n t ( " B : \ ( b ) " ) }

Slide 21

Slide 21 text

例 2: 同じもの違うパターンで表現している l e t t u p l e : ( A ? , B ) = . . . s w i t c h t u p l e { c a s e ( . S o m e ( l e t a ) , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) c a s e ( . N o n e , l e t b ) : p r i n t ( " A : n i l , B : \ ( b ) " ) } s w i t c h t u p l e { c a s e ( l e t a ? , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) c a s e ( . N o n e , l e t b ) : p r i n t ( " A : n i l , B : \ ( b ) " ) } s w i t c h t u p l e { c a s e ( l e t a ? , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) c a s e ( l e t a , l e t b ) : p r i n t ( " A : \ ( a ) , B : \ ( b ) " ) }

Slide 22

Slide 22 text

ところで、普通の switch はどうなってたの?

Slide 23

Slide 23 text

Int とか Range とか l e t i n t : I n t = . . . s w i t c h i n t { c a s e 1 : p r i n t ( " 1 " ) c a s e 3 . . < 1 0 : p r i n t ( " 3 . . < 1 0 " ) } どのパターンが使われているかわかりますか?

Slide 24

Slide 24 text

正解は expression pattern f u n c ~ = < T : E q u a t a b l e > ( a : T , b : T ) - > B o o l f u n c ~ = < I : F o r w a r d I n d e x T y p e w h e r e I : C o m p a r a b l e > ( p a t t e r n : R a n g e < I > , v a l u e : I ) - > B o o l 標準ライブラリで~ = が定義されている

Slide 25

Slide 25 text

アプリ開発での使いどころ

Slide 26

Slide 26 text

UITableViewController c l a s s M y T a b l e V i e w C o n t r o l l e r : U I T a b l e V i e w C o n t r o l l e r { / / セルがA , B , C の三種類あるとする e n u m C e l l T y p e { c a s e A c a s e B c a s e C v a r r e u s e I d e n t i f i e r : S t r i n g { s w i t c h s e l f { c a s e . A : r e t u r n " A " c a s e . B : r e t u r n " B " c a s e . C : r e t u r n " C " } } } . . . } セルの種類が複数あると期待通りの型のセルが dequeue できたか 確認するのもだるいし安全にキャストしていくのもだるい

Slide 27

Slide 27 text

UITableViewController 期待している種類と実際に dequeue されたセルの型を 同時にマッチングしてあげればそこまでだるくない o v e r r i d e f u n c t a b l e V i e w ( t a b l e V i e w : U I T a b l e V i e w , c e l l F o r R o w A t I n d e x P a t h i n d e x P a t l e t c e l l T y p e = / * i n d e x P a t h などからセルの種類を決める * / l e t c e l l = t a b l e V i e w . d e q u e u e R e u s a b l e C e l l W i t h I d e n t i f i e r ( c e l l T y p e . r e u s e I d e n t i f i e r , f o r I n d e x P a t h : i n d e x P a t h ) s w i t c h ( c e l l T y p e , c e l l ) { c a s e ( . A , l e t c e l l a s C e l l A ) : / / c e l l はC e l l A として扱える c e l l . c e l l A L a b e l . t e x t = " H e l l o ! " d e f a u l t : f a t a l E r r o r ( " U n e x p e c t e d c e l l d e q u e u e d . " ) } r e t u r n c e l l }

Slide 28

Slide 28 text

まとめ パターンの文法は初見では難しいが 1 度理解すれば簡単 複数のパターンの組み合わせで値の性質を表現する 標準ライブラリでいくつか expression pattern が用意されている アプリ開発でも使いどころはある