こんにちは。Quipper採用担当の鈴木です。今回の記事は、@geckourによる「Kotlin の scope functions との上手な付き合い方」です!是非、ご覧ください!
こんにちは、Native チームの @geckour です。
今回は、Kotlin の便利な関数である scope functions の概要と、そのうまい使い所の話をします。
Scope functions
Kotlin の scope functions として紹介されているものはいくつかのタイプに分類することができます。
そんな中で、同じような働きをする let apply also
の使い分けで悩んだことがある方も多いのではないでしょうか。
そこで、私達のチーム (僕) が辿った思考/志向の推移を紹介します。
パターン1: 返す値の特性で考える
少し話はそれますが、僕は .forEach {}
で済むところにわざわざ .map {}
を使うのは邪道である、という考えを持っています。.map {}
は拡張元のリストをスコープ内で加工した値のリストに変換して返却しますが、その返却された値を使わないのであれば .forEach {}
を使えばいいし、不用意に .map {}
を使うと「ああこの値は後で使うんだな」というミスリーティングを招いたり、他人がそのコードをいじる際にバグを生みやすくなると考えているからです。
その考え方をもとに、 let
は加工した値を返すので、その値をスコープ外で必要としていない場合には使用を避けるべきでは?という考えに至りました。
つまり、基本的には apply
/ also
を使って、加工した値が必要なときだけ let
を使うという方針です。
よーし、これで心置きなく scope functions を使えるぞ、と思っていた矢先、公式ドキュメント に不穏な(?)記述を発見しました。
つまり、「一時的なスコープ作るのに便利だよ」と言っているくらいなので、値を返すかどうかなどどうでも良さげなスタンスだったのです。
では apply
の立場は…?と思い確認すると
とあり、つまりは「その名の通りオブジェクトをいじるときに使えるぜ」ということらしいのです。
パターン2: メソッド名に従う
はて…ならば全てメソッド名が示すとおりに使い分ければいいのでは?と思い、最近はこのパターンを採用しています。
- Safe call operator (
?.
) を使うときはlet
- あるオブジェクトに対する処理をまとめたいときは
apply
- ネストが深くなって
this
が何なのかわかりづらくなるがスコープは作りたいときはlet
- ネストが深くなって
- あるオブジェクトを生成するついでに何かしたいときも
apply
のような感じです。
おや、 also
はどこに…?と気付いた方。ほぼ使わなくなりました。
終わりに
Kotlin は柔軟で自由である分、正攻法がわからず困ってしまう場面も多いと思います。
正解がわからずとも、これからもより良い方法を考えていく所存です。
皆さんのプラクティスもぜひ聞かせてください!
Quipper では一緒に働く仲間たちを募集しています。
是非お気軽にカジュアル面談にお越しください!