Einführung
Kotlin selbst ist ein sehr leistungsfähiges Tool, aber viele nutzen es oft nicht in vollem Umfang und verwandeln es in eine Art ... Java 6. Ich werde versuchen, Ihnen zu sagen, warum Sie dies nicht tun sollten und wie Sie es verwenden die funktionalen Merkmale der Sprache in vollen Zügen.
Funktionen höherer Ordnung
Ich werde mit ihnen beginnen. Gleichzeitig erkläre ich Ihnen, worum es geht: Wenn eine Funktion eine andere Funktion als Parameter verwendet oder zurückgibt, handelt es sich um eine Funktion höherer Ordnung. Einfach, nicht wahr? Aber wie benutzt du es?
Die Tatsache, dass Funktionen in Kotlin andere Funktionen für uns empfangen und zurückgeben können, sollte bedeuten, dass wir sie in eine Variable schreiben können. Es wird ungefähr so aussehen:
val foo: () -> Unit = { }
Dann können wir es mit folgender Syntax übergeben:
run(foo)
Großartig, aber was ist, wenn wir eine Funktion verwenden möchten, die wir auf normale Weise definiert haben? Oder überhaupt eine Methode bestehen? Nun, auch dafür gibt es eine Möglichkeit - eine Verknüpfung zu einer Funktion . So können wir einen String auf Leere prüfen:
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)
In diesem Fall habe ich zwei Neuigkeiten: Die erste ist, dass Ihr Geschmack sehr spezifisch ist, und die zweite ist, dass in diesem Fall unsere Erweiterungsfunktion als die gewöhnlichste Funktion verarbeitet wird, bei der der erste Parameter eine Instanz der Klasse ist dass es sich ausdehnt.