iOSエンジニアのつぶやき

毎朝8:30に iOS 関連の技術について1つぶやいています。まれに釣りについてつぶやく可能性があります。

Swift5.3 つまみ食い【where clauses on contextually generic declarations編】

今日から少しの間、開発作業が多くなりブログにまとまった時間が取れそうにないので、1日1Tips にもっとも良さそうな Swift5.3 の変更点を書いて行こうかと思います🧑🏻‍💻

where clauses on contextually generic declarations

This proposal aims to lift the restriction on attaching where clauses to member declarations that can reference only outer generic parameters. Simply put, this means the 'where' clause cannot be attached error will be relaxed for most declarations nested inside generic contexts:

参照: https://github.com/apple/swift-evolution/blob/master/proposals/0267-where-on-contextually-generic.md#introduction

以前は一部のオブジェクトのみが参照できるように制限をつける際は Extension で where 句を設定する必要がありましたが、Swift5.3 からはそれらの制約が緩和されて、Extension 内でなくとも、メンバー毎に直接 where で制限を設けることができるようになったそうです。

// Swift5.2以前

struct Box<Wrapped> {
}
extension Box where Wrapped: Sequence {
    func boxes() -> [Box<Wrapped.Element>] { ... }
}
// Swift5.3
struct Box<Wrapped> {
    func boxes() -> [Box<Wrapped.Element>] where Wrapped: Sequence { ... }
}

これによってドキュメントのサンプルにも載っているように、Extension で参照制限をして、メンバー内でさらに制限するなどのことが行えるようになります✍️ それぞれ、Extension で切り出さなくても、ある程度の粒度でまとめられるから便利ですね!

// 'Foo' can be any kind of nominal type declaration.
// For a protocol, 'T' would be Self or an associatedtype.
struct Foo<T>  

extension Foo where T: Sequence, T.Element: Equatable {
    func slowFoo() { ... }
}
extension Foo where T: Sequence, T.Element: Hashable {
    func optimizedFoo() { ... }
}
extension Foo where T: Sequence, T.Element == Character {
    func specialCaseFoo() { ... }
}

extension Foo where T: Sequence, T.Element: Equatable {
    func slowFoo() { ... }

    func optimizedFoo() where T.Element: Hashable { ... }

    func specialCaseFoo() where T.Element == Character { ... }
}

参考

swift.org

github.com

その他の記事

yamato8010.hatenablog.com

yamato8010.hatenablog.com

yamato8010.hatenablog.com