Introdução
O próprio Kotlin é uma ferramenta muito poderosa, mas muitas vezes não o usa em sua capacidade total, transformando-o em algum tipo de ... Java 6. Vou tentar dizer por que você não deve fazer isso e como usar as características funcionais da linguagem ao máximo.
Funções de ordem superior
Vou começar com eles. E, ao mesmo tempo, direi do que se trata: quando uma função recebe outra função como parâmetro ou a retorna, é uma função de ordem superior. Simples, não é? Mas como você usa isso?
O fato de que funções no Kotlin podem receber e retornar outras funções para nós deve significar que podemos escrevê-las em uma variável. Vai parecer algo assim:
val foo: () -> Unit = { }
Então, podemos passá-lo usando uma sintaxe como:
run(foo)
Ótimo, mas e se quisermos usar uma função que definimos da maneira normal? Ou então passar um método? Bem, também existe uma possibilidade - um link para uma função . É assim que podemos verificar se uma string está vazia:
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)
Nesse caso, tenho duas novidades - a primeira é que seus gostos são muito específicos, e a segunda é que, neste caso, nossa função de extensão é processada como a função mais comum, em que o primeiro parâmetro é uma instância da classe que se estende.