LoginSignup
7
4

More than 3 years have passed since last update.

Kotlinの拡張関数や拡張パラメータへの呼び出し時にex.を挟むようにする

Last updated at Posted at 2020-01-17

三行で

"abcd".ex.doubleStr() // abcdabcd
Optional.of(3).ex.unwrap // 3

拡張関数、拡張パラメータの呼び出しが上のようにex.を挟むことができます。

これはつまり?

Kotlinの拡張関数、拡張プロパティ便利だけど、標準やライブラリの拡張関数、拡張プロパティとは区別ができるようにしたいので、呼び出す前にex.を付けられるようにしてみた。と言う話です。

きっかけ

最近Swift界隈では拡張関数や拡張パラメータにアクセスする時に、Rxの拡張関数だとrx.、自前の拡張関数だとex.みたいなものが流行っている(?)みたい話を耳にしたので、Kotlinでも同じようにしたい!!と思ったので作りました。

例えばこんな感じのやつです
https://qiita.com/tattn/items/dc7dfe2fceec00bb4ff7#exでアクセスできるプロパティやメソッドを作る

実装

Swiftのコードを見ると難しそうに見えますが、やってみると意外に簡単でした。
実際のコードです。

data class TargetedExtension<out Base>(val base: Base)
val <Compatible> Compatible.ex: TargetedExtension<Compatible>
    get() = TargetedExtension(this)

これだけです。めっちゃ簡単ですね。

Sample Code

早速これを使って、どう拡張関数、拡張パラメータを定義する必要があるのか見てください。

// 拡張関数定義
fun TargetedExtension<String>.doubleStr(): String = base + base
fun TargetedExtension<Int>.square(): Int = base * base
// 拡張パラメータ定義
val TargetedExtension<String>.doubleStrValue: String
    get() = base + base
val TargetedExtension<Optional<Int>>.unwrap: Int
    get() = base.get()
val TargetedExtension<Number>.half
    get() = base.toDouble() / 2

"test".ex.doubleStr() // testtest
12.ex.square() // 144
"abc".ex.doubleStrValue // abcabc
Optional.of(3).ex.unwrap // 3
3.55.ex.half //1.775

(思ったように動いて安心しました)

コードの説明

以下拡張関数、拡張パラメータの説明が重複するので、拡張パラメータを使ったパターンについての説明をします。
拡張関数の説明も拡張パラメータと同じです。

3.55.ex.half

を分解すると左から

  1. 3.55: 本来拡張変数を持たせたい型のインスタンス(レシーバ)
  2. ex: 型パラメータを使って定義されたex拡張パラメータ(関節レシーバ)
  3. half: 関節レシーバから呼び出された拡張関数((関節)レシーバの拡張パラメータ)

本来は13の部分だけで構成して関節部分を挟まない定義が当たり前ですが、3の部分の定義を2exが返すインスタンスの型の拡張パラメータとして定義することで、間にexを挟めるようにしたと言うことです。

3.55(本レシ).ex(関節レシ).half(関節レシバに定義した拡張パラメタ)
  • 本レシーバのインスタンスをTargetedExtensionでラップしたインスタンスをexからもらえるようにする。
  • TargetedExtensionの型パラメータを指定した拡張関数を定義する。

の複合要素の合体技という感じで、ちょっと直感的じゃないのが難点かなという気がしますが、慣れたら問題はないかなぁという気がしています。型パラメータをつなぐ使い方がテクニカルなポイントでしょうか。


  • ライブラリやなんかの拡張関数、拡張パラメータとは呼び方を変えたい
  • 自分のライブラリの拡張関数、拡張パラメータは、特別なアクセスのさせ方をしたい
  • 自作のものが他と被るのが嫌だったから拡張関数、拡張パラメータの利用を避けていたけど、それがこれなら問題がクリアされる

みたいに刺さればいいなと思っています。
以上。

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4