Patterns in Swift

8889da6a67db3667b0694d993c9a962c?s=47 Yosuke Ishikawa
August 29, 2015
7k

Patterns in Swift

8889da6a67db3667b0694d993c9a962c?s=128

Yosuke Ishikawa

August 29, 2015
Tweet

Transcript

  1. Patterns in Swift ishkawa

  2. None
  3. 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 ) }
  4. 問題点 文法がよくわからん

  5. 例 1

  6. 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 ) " ) }
  7. これでもいいの? 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 ) " ) }
  8. 例 2

  9. 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 ) " ) }
  10. これでもいいの? 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 ) " ) }
  11. これも同じ???? 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 ) " ) }
  12. None
  13. パターンの文法を知らないと ... 込み入った switch 文が読めない 愚直な switch 文しか書けない ググってみるけどよくわからなくて時間を浪費する 結果的に劣等感に悩まされる

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

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

    Tuple Pattern Enumeration Case Pattern Optional Pattern Type‑Casting Pattern Expression Pattern
  16. 組み合わせ可能 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
  17. 各パターンの仕様 書くのが大変なので公式を参照します The Swift Programming Language Language Reference Patterns

  18. どれも結構使う

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

  20. 例 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 ) " ) }
  21. 例 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 ) " ) }
  22. ところで、普通の switch はどうなってたの?

  23. Int とか Range<Int> とか 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 " ) } どのパターンが使われているかわかりますか?
  24. 正解は 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 標準ライブラリで~ = が定義されている
  25. アプリ開発での使いどころ

  26. 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 できたか 確認するのもだるいし安全にキャストしていくのもだるい
  27. 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 }
  28. まとめ パターンの文法は初見では難しいが 1 度理解すれば簡単 複数のパターンの組み合わせで値の性質を表現する 標準ライブラリでいくつか expression pattern が用意されている アプリ開発でも使いどころはある