Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Patterns in Swift

Yosuke Ishikawa
August 29, 2015
8k

Patterns in Swift

Yosuke Ishikawa

August 29, 2015
Tweet

Transcript

  1. Patterns in Swift
    ishkawa

    View Slide

  2. View Slide

  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
    )
    }

    View Slide

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

    View Slide


  5. 1

    View Slide

  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
    )
    "
    )
    }

    View Slide

  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
    )
    "
    )
    }

    View Slide


  8. 2

    View Slide

  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
    )
    "
    )
    }

    View Slide

  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
    )
    "
    )
    }

    View Slide

  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
    )
    "
    )
    }

    View Slide

  12. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  18. どれも結構使う

    View Slide

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

    View Slide


  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
    )
    "
    )
    }

    View Slide


  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
    )
    "
    )
    }

    View Slide

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

    View Slide

  23. 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
    "
    )
    }
    どのパターンが使われているかわかりますか?

    View Slide

  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
    標準ライブラリで~
    =
    が定義されている

    View Slide

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

    View Slide

  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
    できたか
    確認するのもだるいし安全にキャストしていくのもだるい

    View Slide

  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
    }

    View Slide

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

    View Slide