9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Swift] ジェネリクスよりも型消去ラッパー型を考える

Last updated at Posted at 2019-10-14

Characterシーケンスを受け取り、Tokenを返す関数を考えます。

func convertToken(from chars: [Character]) -> Token { ...

上記のようにArray<Character>型として引数を宣言すると、文字列からこの関数を呼び出すたびにArray型を生成するというコスト(O(N))が発生します。

// Array型を生成するコストが発生する
converToken(Array("Hello World"))

そもそもconvertToken関数は、Characterシーケンスを受け取れれば良いので、Array型である必要はありません。

しかしながらSwiftは、Selfassociatedtypeを持つプロトコルは型宣言として利用することが出来ません。

// NG
func convertToken(from chars: Sequence) -> Token { ...

ただし型制約としては使用することが出来る。

// OK
func convertToken<T>(from chars: T) -> Token where T: Sequence, T.Element == Character { ...

また関数をジェネリクス化した場合は、引数の生成コストが0になります。

// 生成コスト0で呼び出せる
convertToken(from: "Hello World")

が、一見、何を受け取るのかわかりにくくなります。
そこで型消去ラッパー型として用意されている AnySequence 型の出番です。

func convertToken(from chars: AnySequence<Character>) -> Token { ...

以下のように文字列、配列であろうが、Characterのシーケンスを渡すことが出来、こちらも生成コストが0です。

// 文字列から
convertToken(from: AnySequence("Hello World"))

// 配列Array<Character>から
convertToken(from: AnySequence(str.soreted()))

str.sorted()の戻り値は[Character]です。したがってconvertToken(form:)関数がもし以下のように定義されてしまうと、つなぐためには文字列に再度変換する必要が出来ます。

// 文字列を直接受け取ることにした場合
func convertToken(from str: String) -> Token { ... }

// 一旦Stringを再生成
convertToken(String(str.sorted()))

またジェネリクスと比較では、並べてみるとどちらがリーダブルかは明白です。

func convertToken<T>(from chars: T) -> Token where T: Sequence, T.Element == Character { ... 
func convertToken(from chars: AnySequence<Character>) -> Token { ...

まとめ

Swift標準ライブラリーではAnySequce以外にも沢山の型消去ラッパー型が用意されています。(Any*~系は型消去ラッパー型です。)
ジェネリクスを使う前に一旦そちらを使用することも検討してみてください。

参照

AnySequence型
https://developer.apple.com/documentation/swift/anysequence

型消去の使い方 in Swift
https://yossan.hatenablog.com/entry/2019/10/14/172457

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?