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