Swift4で数値、配列、Enumに対してのExtension

最近SwiftでiOSアプリ作ったり、フレームワークを作ったりすることが多いのですが、その中で Extension 使って整数型や文字列型に機能追加することが多々ありました。

備忘録として実装方法・実装内容などを記載しておきます。

環境

  • Swift 4

Extensionいろいろ

数値型に対しての Extension

Swift で数値というと真っ先に思いつくのが Int かとおもいます。

Int に対してだけ拡張を適応させたければ extension Int とすれば良いのですが、UInt や Int64 なども含めて広い範囲で拡張を適用したい場合は適切な Protocol を拡張する必要があります。

数値型の Protocol の拡張・実装関係を調べたところ下図のようになってました。

スペースの都合で端折ってますが、UInt8 や UInt32 は図中の UInt と同じプロトコルを、Int8 や Int32 は図中の Int と同じプロトコルを、実装しています。

符号有無を含めてすべての整数型に対しての機能を追加する場合は BinaryInteger あたりがよさそうです。

使用例

今回実装したのは、整数型とバイト配列へのシリアライズ・デシリアライズ処理、16進表記の文字列へのコンバート処理です。

文字列に対しての Extension

文字列に対しての Extension はわかりやすいですね。extension String です。
今回実装したのは、文字列が正規表現を満たすかを調べるというものです。

使用例

配列に対しての Extension

配列に対しての Extension は Array を拡張すれば良いのですが、特定の型を要素として持つ配列のみ拡張したい場合は Swift 4で導入された条件付き適合(Conditional Conformances)という機能を使います。

今回実装したものだと、UInt8 の配列を16進数値表記の文字列にコンバートするというものです。where 以降が条件付き適合の条件の部分ですね。

使用例

同じように、辞書型でも Key と Value の型で条件付き適合できます。

Enum に対しての Extension

特定の Enum に対しての Extension ではなく、特定の RawValue の型をもつ Enum を拡張する場合の話です。

Swift で Enum を定義するとき、下記のように書くと、

let value = TestEnum(rawValue: 1) というように、RawValue から Enum値を取得することができますね。
このように RawValue を使って初期化ができる Enum は、RawRepresentable というプロトコルが実装されていますので、このプロトコルを拡張することで少し汎用的な拡張ができます。

今回実装したのだとこんな感じ。

RawValue が BinaryInteger を実装したクラス(Int、UInt8 など)をもつ場合に、Int を渡して Enum 値を生成、できなければ例外を投げるというものです。
(本当はもっと複雑なことをしてましたが、簡略化してます)

さいごに

同じことを何度も調べているような気がしたので、ブログに書いておきました。

どうでも良いですが、記事内のクラス図、 Powered by PlantUML です。


最後まで読んでいただきありがとうございます。 このブログを「いいな」と感じていただけましたら、Twiter にてフォローいただけるとうれしいです。ブログ更新情報などもお届けします。



この記事をシェアする




りゅーた
フリーランスのエンジニアしてます。Android、iOS アプリの開発、対向サーバの開発、C/C++のライブラリ開発が現在のメイン。趣味はテニス。3児の父。 もっと詳しく

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA