Dans «Spring with Kotorin - 6. Asynchronous processing», la description suivante a été faite lors de la définition des propriétés de l'instance. C'était.
@Bean
fun normalTaskExecutor(): TaskExecutor = ThreadPoolTaskExecutor().apply {
corePoolSize = 1
setQueueCapacity(5)
maxPoolSize = 1
setThreadNamePrefix("NormalThread-")
setWaitForTasksToCompleteOnShutdown(true)
}
Il crée une instance ThreadPoolTaskExecutor, puis lambda opère sur cette instance.
De cette manière, la fonction utilisée pour effectuer des opérations sur le lambda suivant l'instance est appelée la ** fonction scope **. L'utilisation de ce format est pratique dans les points suivants.
Kotlin a plusieurs fonctions de portée. Chacun est utilisé différemment, alors vérifions à quoi il ressemble.
Il est implémenté dans l'environnement suivant, mais ce n'est pas une prémisse particulière.
Spring Dependencies
Les fonctions de portée sont les suivantes.
Regardons chaque fonction.
Tout d'abord, regardons la définition de chaque fonction de portée.
Scoping Function | Définition | Exemple |
---|---|---|
with | fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() | val r: R = with(T()) { this.foo(); this.toR() } |
run | fun <T, R> T.run(block: T.() -> R): R = block() | val r: R = T().run { this.foo(); this.toR() } |
let | fun <T, R> T.let(block: (T) -> R): R = block(this) | val r: R = T().let { it.foo(); it.toR() } |
apply | fun |
val t: T = T().apply { this.foo() } |
also | fun |
val t: T = T().also { it.foo() } |
En regardant la définition, vous pouvez voir que le mode de définition est largement différent des deux points de vue suivants.
--Représentation du destinataire
--T. () -> R
: Fonction d'extension du récepteur de type T
-- (T) -> R
: traite le type de récepteur T comme argument
R = block ()
: Renvoie le résultat de lambda
--return this
: Renvoie le récepteurPour résumer ce qui précède, nous avons la matrice suivante.
Préparez la classe de données suivante en tant qu'objet récepteur.
data class Person(
var name: String,
var age: Int
) {
private lateinit var hobby: String
fun nameToUpperCase() {
name = name.toUpperCase()
}
fun increaseAge() {
age++
}
fun defineHobby(hobby: String) {
this.hobby = hobby
}
fun displayHobby() = this.hobby
fun toStringAddon(): String {
return "Person(name=$name, age=$age, hobby=$hobby)"
}
}
with
with
est une fonction ordinaire, pas une fonction d'extension du récepteur.
Par conséquent, il est appelé différemment des autres fonctions d'étendue.
val foo: Person = Person("with", 20)
with(foo){
foo.increaseAge()
println(foo)
}
run
run
utilise this
pour représenter le récepteur dans le lambda.
Par conséquent, il est ** facultatif **.
Dans ce qui suit, il est explicitement décrit, mais il est souvent omis car il est redondant.
Il renvoie également le résultat lambda (dernière ligne).
val foo: Person = Person("run", 20)
return foo.run {
nameToUpperCase()
println(this)
this.name
}
let
let
se comporte un peu comme courir, mais
La représentation du récepteur dans le lambda est ʻit`.
Par conséquent, il peut s'agir d'un ** alias **.
Remplacez-le par un mot clé qui a du sens
Il est utilisé pour améliorer la lisibilité.
val foo: Person = Person("let", 20)
return foo.let { it ->
println(it)
it.defineHobby("Kotlin")
println(it.toStringAddon())
it.displayHobby()
}
apply ʻApply` renvoie le récepteur lui-même. Par conséquent, il est utilisé lors du fonctionnement du récepteur lui-même. Il est utilisé à de nombreuses fins telles que la définition et la modification des propriétés. Le récepteur est représenté par «ceci». Ici, il est omis dans l'appel de fonction du récepteur.
val foo: Person = Person("apply", 20)
foo.apply {
println(this)
nameToUpperCase()
increaseAge()
println(this)
}
also Vous pouvez penser à «aussi» que la représentation du récepteur de apply est maintenant «it». Par conséquent, il est utilisé lorsqu'il est nécessaire de donner un alias au récepteur pour améliorer sa lisibilité.
val foo: Person = Person("also", 20)
return foo.also { it ->
println(it)
it.nameToUpperCase()
it.increaseAge()
it.defineHobby("Kotlin")
println(it.toStringAddon())
}
Personnellement, l'utilisation correcte de la fonction scope est déterminée uniquement par le fait que vous souhaitez ou non renvoyer le récepteur comme valeur de retour. Après cela, si le mot clé this semble compliqué, je vais l'utiliser correctement en m'abstenant.
Recommended Posts