メモを揉め

お勉強の覚書。

swift_combination を Swift 3.0 に対応させました

Xcode 8.0 がリリースされていたので早速インストールして Swift 3.0 を試してみた。
拙作のライブラリ swift_combination を開いてみると既存のコードを Swift 3.0 のシンタックスにコンバートするか聞かれたので、とりあえずつっこんでみる。

memowomome.hatenablog.com

下のコードは配列の長さを指定して 0 で埋めるという処理だが、微妙に API の名前が変わってたりした。

var indices = [Int](count: length, repeatedValue: 0) // before
var indices = [Int](repeating: 0, count: length)     // after

もう一箇所は for in を使ってる箇所で enumerateenumerated に変更されている。

for (i, slct) in unselected.enumerate() { // before
  ...
}
for (i, slct) in unselected.enumerated() { // after
  ...
}

細かい API の変更は全部これで直してくれるっぽい。

手動で直した箇所

ビルドしてみると以下の2点で警告が出た。

第一引数をラベル無し引数で渡す場合は明示的に指定する必要がある

Swift 3.0 では基本的に引数のラベルは省略しない事になったらしい。

let combos = combination([0, 1, 2], length: 2)      // before
let combos = combination(arr: [0, 1, 2], length: 2) // after

ライブラリはこれに合わせて全部ラベル付きで呼び出すように修正したけど、ラベルを省略したコードをそのまま動かしたい場合は、関数定義の引数ラベルの前に _ を付ければ一応オッケーらしい。

public func combination<T>(arr:[T], length:Int? = nil) -> [[T]] {   // before
  ...
}
public func combination<T>(_ arr:[T], length:Int? = nil) -> [[T]] { // after
  ...
}

関数の戻り値を使用しない場合は明示的に指定する必要がある

関数定義の方で戻り値を指定している場合、それを使わないと警告が出る。
_ = myFunc() のように _ への代入を書くか、関数定義の上に @discardableResult を付けることで警告を消すことができた。

_combination(arr: arr, length: _len){ ret.append($0) }     // 警告が出る
_ = _combination(arr: arr, length: _len){ ret.append($0) } // 警告が消える

@discardableResult // これがあれば戻り値を破棄出来る
internal func _combination<T>(arr:[T], length:Int, process:([T]) -> ()) -> [T] {
  ...
}

とりあえず @discardableResult を関数定義に付ける方向で対応することにした。