概要
あるソースを読んでいたら、
公式リファレンスで見たこと無い記法に出会ったので備忘録として残しておきます。
該当部分
下記で変数にインスタンスを代入する際、
変数 = クラス名 {...}
というコードを見かけました。
val examplesAdapter = HomeOptionsAdapter {
val fragment = it.createView()
...
}
Object expressions の省略記法かなと思ったのですが、
it
があるのでlambdasのような気がしました。
結論
trailing lambda
記法でした。
trailing lambda とは
Kotlinでは、関数の最後のパラメータが関数である場合、そのパラメータは括弧の外に指定することができるという慣習があります
関数を引数に取る関数があります。
fun calc(action: ()->Unit): Long {
var start = System.currentTimeMillis()
action()
var end = System.currentTimeMillis()
return end - start
}
このように呼び出すところを、
val time = calc ({
var x = 1
for (i in 1..10_000_000) {
x++
}
})
trailing lambda
に基づき、引数を表現するための()
を省略して呼び出すことができます。
val time = calc {
var x = 1
for (i in 1..10_000_000) {
x++
}
}
ここまでは公式リファレンスに書いてあります。
trailing lambda が constructor にも使える
今回のケースだと、HomeOptionsAdapter
は、constructorに関数を取るClassです。
class HomeOptionsAdapter(val onClick: (ExampleItem) -> Unit)
このクラスをインスタンス化する際、
val examplesAdapter = HomeOptionsAdapter({
val fragment = it.createView()
...
})
と記載するところを
val examplesAdapter = HomeOptionsAdapter{
val fragment = it.createView()
...
}
のように記載できます。
constructorも関数だと思えば、この記法が有効であることも納得できました。
trailing lambda
が constructor でも使えることは知らなかったです。
省略記法を用いないと ...
it も省略記法ですので、省略記法を用いない場合は下記です。
※ it について : 関数リテラルがパラメータを1つだけ持つ場合、その宣言を( -> と一緒に)省略してもよい
val examplesAdapter = HomeOptionsAdapter ({ ExampleItem ->
val fragment = ExampleItem.createView()
...
})
最後に
省略記法が複数用いられていると、よくわからなくなることがあります。
短くかければ良いというものではないなぁ、と思いました。
個人的に読みやすいコードにするために trailing lambda
を用いずに、コンストラクタであることを明示的に書こうとしたら、
Android Studio上のLinterが走り、省略記法で記載するよう促されましたので、推奨されている書き方ではあるのかもしれません。