SwiftLint 0.22で追加された multiple_closures_with_trailing_closure
というルールをご存知でしょうか。これは次のような複数のクロージャを引数に取るAPIを使用する時に、最後の引数のクロージャをTrailing Closureとして渡すことを警告するというルールです。
func fetch(id: Int, success: () -> Void, failure: (Error) -> Void) { ... } // NG fetch( id: 12345, success: { print("success") } ) { error in print("error: \(error)" } // OK fetch( id: 12345, success: { print("success") }, failure: { error in print("error: \(error)")} )
こうしたAPIでは最後のクロージャだけ引数ラベルが落ちてしまうと、各引数の間の対称性がなくなってしまってコードが読みにくくなってしまいそうです。普段よく使うであろうAPIとしては UIView.animate(withDuration:animations:completion:)
が挙げられると思います。
// With trailing closure UIView.animate( withDuration: 0.3, animations: { ... } ) { finished in ... } // Without trailing closure UIView.animate( withDuration: 0.3, animations: { ... }, completion: { finished in ... } )
さて、Lintで利用者側がこうした使用方法を警告・禁止できるとしても、ライブラリの提供者側で禁止することはできないでしょうか。以下に1つのアイデアを示してみようと思います。
func fetch(id: Int, success: () -> Void, failure: (Error) -> Void, _ tcDisabler: () = ()) { ... }
考え方としては単純で、クロージャが最後の引数にならないようにしてあげるだけですね。意味のない値をデフォルト引数として設定しておくことで、利用者サイドは特に気にせずに利用できるはずです。引数名や値に考える余地はありそうですが、他にもいい手段がないか、ご意見お待ちしています。