[Swift] AnyGeneratorの今後

Tuesday, March 22, 2016

仕事を終えて家でぼちぼちXcode7.3で作ったライブラリのプロジェクト開いてうんうん唸っています。どうも。
今日はとりあえず、人の目に多く触れそうなものから修正しました。

今回修正した内容は、

  • typealiasassociatedtypeに変更
  • anyGenerator() 関数を AnyGenerator のイニシャライザに変更
  • EnumerateSequence のイニシャライザを AnySequence.enumerate() に変更

です。
Swift2.1.1からSwift2.2になることで、Warningがでたりするので、ぼちぼち変更していく感じです。
少し、 AnyGeneratorEnumerateSequence に関して掘り下げて見ていきます。

anygenerator() 関数を変更する

anyGenerator() 関数は、Swift2.2から非推奨、3.0で廃止になります。
代わりに、AnyGeneratorのイニシャライザを使います。

// Before
anyGenerator {
    // 処理
    return element
}

// After
AnyGenerator {
    // 処理
    return element
}

イニシャライザは以下のように宣言されています。

public struct AnyGenerator<Element> : GeneratorType {
    public init<G : GeneratorType where G.Element == Element>(_ base: G)
    public init(body: () -> Element?) // ★
}

★がついている方を使います。こちらのイニシャライザは、() -> Element?型のclosureになっていて、

public func anyGenerator<Element>(body: () -> Element?) -> AnyGenerator<Element>

もとの anyGenerator 関数と取る引数が同じです。なので、書き換える時は、 aA に変えるだけで済みます。
一文字違いですが、関数とイニシャライザの違いには留意しておきたいところです。

EnumerateSequenceのイニシャライザを使わなくする

Swift2.1.1までは、 EnumerateSequence のイニシャライザに AnySequence を渡すことができましたが、これも非推奨になってしまいました。
ただ、しっかりケアをしてくれていて、enumerate()を使いなさいねーって警告を出してくれます。
なので、以下のように書き換えます。

// Before
public static func enumerate() -> EnumerateSequence<AnySequence<Int>> {
    return EnumerateSequence(AnySequence(generator))
}

// After
public static func enumerate() -> EnumerateSequence<AnySequence<Int>> {
    return AnySequence(generator).enumerate()
}

更にSwift3.0まで考えてみる

現在Swiftのリポジトリは3.0に向けてガシガシ開発が進んでいて、masterブランチで3.0の片鱗を見ることができます。
そこで色々見てみると、

  • AnyGeneratorはAnyIteratorにリネームされている
  • EnumerateSequenceはEnumeratedSequenceにリネームされている

ことが分かります。
Swift3.0から、API Guidelineに従って、より良い名前にリネームされるものが多くあります。

この中に上記2つも含まれています。
なので、Swift3.0での リネーム祭り には備えておかないといけないですね。(おそらくXcodeならマイグレーション機能とか用意してくれそうだけど…)
ちなみに、Generator系は総じてIteratorに変わるようです。

Swift3.0が出るのは先ですが、Swift2.2にぼちぼち乗り換えつつ、
Swift3.0への乗り換えの心構えもしておくといいのかもしれません。

techSwiftTips

しばらくはcarthageでライブラリを更新するときは--no-use-binariesを付けたほうが良さそう

文字列を指定した長さずつ分割する