この記事は、ACCESS Advent Calendar 2018 4日目の記事です。
はじめに
thisを返す関数の実装方法についてです。
Builderパターンにおいてメソッドチェーンをよく使いますが、Kotlinには Default arguments があるため、BuilderパターンもKotlinではあまり使うことはないかなと思っていました。
が、
- Kotlin Fest 2018でのあんざいゆきさんのスライドでの例 のように、Builderパターンが有効なケースもある
- テストコードでメソッドチェーンを使うことは多い
ということで、
最近試した、メソッドチェーンのためにthisを返す関数の実装方法を紹介します。
普通にやると
val neko: Neko = Neko().foo().bar()
class Neko {
fun foo(): Neko {
// do something
return this
}
fun bar(): Neko {
// do something
return this
}
}
上記のように、戻り値の型を明記したり return this
を書くのは、ちょっと冗長です。
apply()
を expression body として使う
val neko: Neko = Neko().foo().bar()
class Neko {
fun foo() = apply {
// do something
}
fun bar() = apply {
// do something
}
}
かなりシンプルになりました。
継承して使うには、もう一工夫
apply
を使っても戻り値の型は Neko
なので、Self-typeのようには使えず、
継承して使いたいときには困ったりもします。
class MikeNeko : Neko() {
fun baz() = apply {
// do something
}
}
// Compile Error: barの戻り値はMikeNekoではなくNekoであるため。
val tama = MikeNeko().foo().bar().baz()
こういう場合は、拡張関数を使うと、なんとかなります。
open class Neko
fun <T : Neko> T.foo() = apply {
// Nekoを継承したクラスに対してなにか処理してそのインスタンス自体を返す
}
こんなに頑張ってまで、継承を使って一体何を実現するのかという気もしますが、1つのやり方として。
明日の ACCESS Advent Calendar 2018 は @kenrota です。