Kotlin Fungsional. Atas nama kebaikan, pelangi dan sebagainya

pengantar

Kotlin sendiri adalah alat yang sangat kuat, tetapi banyak yang sering tidak menggunakannya hingga kapasitas penuh, mengubahnya menjadi semacam ... Java 6. Saya akan mencoba memberi tahu Anda mengapa Anda tidak boleh melakukan ini dan cara menggunakan fitur fungsional bahasa secara maksimal.





Fungsi tatanan lebih tinggi

Saya akan mulai dengan mereka. Dan, pada saat yang sama, saya akan memberi tahu Anda tentang semua ini: ketika sebuah fungsi mengambil fungsi lain sebagai parameter atau mengembalikannya, itu adalah fungsi tingkat tinggi. Sederhana bukan? Tapi bagaimana Anda menggunakannya?





Fakta bahwa fungsi di Kotlin dapat menerima dan mengembalikan fungsi lain untuk kita berarti bahwa kita dapat menuliskannya ke variabel. Ini akan terlihat seperti ini:





val foo: () -> Unit = {  }
      
      



Kemudian, kita bisa meneruskannya menggunakan sintaks seperti:





run(foo)
      
      



Bagus, tapi bagaimana jika kita ingin menggunakan fungsi yang sudah kita definisikan dengan cara biasa? Atau lulus metode sama sekali? Nah, ada kemungkinan untuk itu juga - tautan ke suatu fungsi . Beginilah cara kita memeriksa kekosongan string:





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)
      
      



Dalam hal ini, saya punya dua berita - yang pertama adalah selera Anda sangat spesifik, dan yang kedua adalah bahwa dalam hal ini, fungsi ekstensi kami diproses sebagai fungsi paling umum, di mana parameter pertama adalah turunan dari kelas bahwa itu meluas.








All Articles