機能的なKotlin。善、虹、その他すべての名において

前書き

Kotlin自体は非常に強力なツールですが、多くの場合、Kotlinを最大限に活用せず、ある種の... Java6に変換します。なぜこれを行うべきではないのかとその使用方法を説明します。言語の機能を最大限に活用します。





高階関数

それらから始めましょう。そして同時に、それが何であるかをお話しします。関数が別の関数をパラメーターとして受け取るか、それを返す場合、それは高階関数です。簡単ですね。しかし、どのように使用しますか?





Kotlinの関数が他の関数を受け取って返すことができるという事実は、それらを変数に書き込むことができることを意味するはずです。次のようになります。





val foo: () -> Unit = {  }
      
      



次に、次のような構文を使用して渡すことができます。





run(foo)
      
      



すばらしいですが、通常の方法で定義した関数を使用したい場合はどうでしょうか。または、メソッドを渡すだけですか?まあ、それも可能性があります-関数へのリンクこれは、文字列の空をチェックする方法です。





str.run(String::isEmpty)
      
      



. , , . , . ? ? "" ?



, , , , - :





val parse: (String) -> List<Int> = { it.split(":").map(String::toInt) }

val (xMin, yMin) = parse(data["from"])
val (xMax, yMax) = parse(data["to"])
      
      



, , , , , .  let



run



with



apply



,  also



. ? , .





inline fun <T, R> T.let(block: (T) -> R): R
inline fun <T> T.also(block: (T) -> Unit): T
      
      



let



also



. , - block(this)



. , " " . , . also



, let



, .





inline fun <R> run(block: () -> R): R
inline fun <T, R> T.run(block: T.() -> R): R
inline fun <T, R> with(receiver: T, block: T.() -> R): R
inline fun <T> T.apply(block: T.() -> Unit): T
      
      



run



, with



apply



:

run



let



, apply also



, with



run



, receiver



. , let



also



? , it



this



, .



? .



, , , , , , . "" .





inline



? , , . , , , , .



. .





, , - ( )?



, , :





let {
  val some = Some()
  it.run(some::doSome)
}
      
      



:





let(Some::doSome)
      
      



, , ?





, , ? , . , companion object



:





class Some {
  companion object {
    fun doSome(any: Any) = run {}
  }
}
      
      



, .





Factory

:





val other = Other()
val stuff = other.produceStuff()

val some = Some(stuff)
      
      



. , Other Some, .





, :





val some = Some(
  Other().produceStuff()
)
      
      



. , , ... ? , Factory-:





class Some {
  companion object Factory {
    inline fun <T>create(t: T?, f: (T?) -> Stuff) = Some(f(t))
  }
}
      
      



:





val some = Some(Other()) { it.doStuff() }
      
      



Other :





val some = Some.create(Other) { it.create().doStuff() }
      
      



, . ? , . , .





-

, - , . , , . :





fun Some.foo() = run { }
      
      



:





val foo: Some.() -> Unit = {  }
      
      



, - . -. , IntelliJ IDEA , - , .





, -. val



, foo



, . fun



, , .





:





class Some {
  fun Other.someExtention() = run { }
}
      
      



, , "", - .





, . . . , , - Some Other.





, , , - Some::someExtention



. , - .





P.S.

, , . , KFunction.





fun Some.overlay(f: KFunction1<Some, Any>) = f(this)
      
      



この場合、2つのニュースがあります。1つはあなたの好みが非常に具体的であるということです。2つ目はこの場合、拡張関数が最も普通の関数として処理され、最初のパラメーターがクラスのインスタンスであるということです。それが拡張すること。








All Articles