[JAVA] Avec Kotorin ―― 7. Fonction de cadrage

Aperçu / Description

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.

Hypothèse / environnement

Il est implémenté dans l'environnement suivant, mais ce n'est pas une prémisse particulière.

Version d'exécution

Spring Dependencies

Environnement de développement

Procédure / Explication

Les fonctions de portée sont les suivantes.

Regardons chaque fonction.

Définition de la fonction de portée

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 T.apply(block: T.() -> Unit): T { block(); return this } val t: T = T().apply { this.foo() }
also fun T.also(block: (T) -> Unit): T { block(this); return this } 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

Pour résumer ce qui précède, nous avons la matrice suivante.

scopingfunction.png

Exemple de code

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())
    }

Résumé / Rétrospective

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.

scopefunction-selection.png

Cette source

Recommended Posts

Avec Kotorin ―― 7. Fonction de cadrage
Printemps avec Kotorin ―― 1. INITIALISATION PRINTEMPS
Fonction sans serveur avec Micronaut
Ressort avec Kotorin ―― 3. Omettre les crochets d'onde de la fonction
Java pour jouer avec Function
Spring with Kotorin --- 8. Couche de référentiel
Spring avec Kotorin --6 Traitement asynchrone
Ressort avec Kotorin ―― 7. Couche de service
Fonction de connexion avec Spring Security
Spring avec Kotorin - 4 Conception d'API REST
Mise en œuvre de la fonction d'authentification avec Spring Security ②
Créer une fonction de pagination avec Rails Kaminari
Mise en œuvre de la fonction d'authentification avec Spring Security ①
[Retrait des rails] Créez une fonction de retrait simple avec des rails
Essayez d'implémenter une fonction de connexion avec Spring-Boot
Fonction d'authentification avec Play Framework [Enregistrement et authentification]
Créez quand même une fonction de connexion avec Rails
Comment implémenter TextInputLayout avec la fonction de validation
Implémenter la fonction de pagination avec Spring Boot + Thymeleaf