[JAVA] Mit Kotorin ―― 7. Scoping-Funktion

Übersicht / Beschreibung

In "Frühling mit Kotorin - 6. Asynchrone Verarbeitung" wurde beim Festlegen der Eigenschaften der Instanz die folgende Beschreibung vorgenommen. Es war.

    @Bean
    fun normalTaskExecutor(): TaskExecutor  = ThreadPoolTaskExecutor().apply {
        corePoolSize = 1
        setQueueCapacity(5)
        maxPoolSize = 1
        setThreadNamePrefix("NormalThread-")
        setWaitForTasksToCompleteOnShutdown(true)
    }

Es erstellt eine ThreadPoolTaskExecutor-Instanz und Lambda verarbeitet diese Instanz.

Die Funktion, mit der Operationen auf dem Lambda ausgeführt werden, die der Instanz auf diese Weise folgen, wird als ** Bereichsfunktion ** bezeichnet. Die Verwendung dieses Formats ist in den folgenden Punkten praktisch.

Kotlin verfügt über mehrere Bereichsfunktionen. Jeder wird anders verwendet, also schauen wir uns an, wie er aussieht.

Annahme / Umwelt

Es wird in der folgenden Umgebung implementiert, ist jedoch keine besondere Voraussetzung.

Laufzeitversion

Spring Dependencies

Entwicklungsumgebung

Vorgehensweise / Erklärung

Die Bereichsfunktionen sind wie folgt.

Schauen wir uns jede Funktion an.

Definition der Scope-Funktion

Schauen wir uns zunächst die Definition der einzelnen Bereichsfunktionen an.

Scoping Function Definition Beispiel
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() }

Wenn Sie sich die Definition ansehen, sehen Sie, dass sich die Art der Definition stark von den folgenden beiden Gesichtspunkten unterscheidet.

Zusammenfassend haben wir die folgende Matrix.

scopingfunction.png

Codebeispiel

Bereiten Sie die folgende Datenklasse als Empfängerobjekt vor.

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 ist eine gewöhnliche Funktion, keine Erweiterungsfunktion des Empfängers. Daher wird es anders als andere Bereichsfunktionen aufgerufen.

    val foo: Person = Person("with", 20)

    with(foo){
        foo.increaseAge()
        println(foo)
    }

run run verwendet this, um den Empfänger im Lambda darzustellen. Daher ist es ** optional **. Im Folgenden wird es explizit beschrieben, aber häufig weggelassen, weil es redundant ist. Es gibt auch das Lambda-Ergebnis (letzte Zeile) zurück.

    val foo: Person = Person("run", 20)

    return foo.run {
        nameToUpperCase()
        println(this)
        this.name
    }

let let verhält sich ähnlich wie run, aber Die Empfängerdarstellung im Lambda ist "es". Daher kann es ** Alias ** sein. Ersetzen Sie es durch ein sinnvolles Schlüsselwort Es wird verwendet, um die Lesbarkeit zu verbessern.

    val foo: Person = Person("let", 20)

    return foo.let { it ->
        println(it)
        it.defineHobby("Kotlin")
        println(it.toStringAddon())
        it.displayHobby()
    }

apply apply gibt den Empfänger selbst zurück. Daher wird es beim Betrieb des Empfängers selbst verwendet. Es wird für viele Zwecke verwendet, z. B. zum Festlegen und Ändern von Eigenschaften.

Hier wird es im Funktionsaufruf des Empfängers weggelassen.

    val foo: Person = Person("apply", 20)

    foo.apply {
        println(this)
        nameToUpperCase()
        increaseAge()
        println(this)
    }

also Sie können sich "auch" vorstellen, da die Empfängerdarstellung von "Apply" jetzt "it" ist. Daher wird es verwendet, wenn es erforderlich ist, dem Empfänger einen Alias zu geben, um seine Lesbarkeit zu verbessern.

    val foo: Person = Person("also", 20)

    return foo.also { it ->
        println(it)
        it.nameToUpperCase()
        it.increaseAge()
        it.defineHobby("Kotlin")
        println(it.toStringAddon())
    }

Zusammenfassung / Rückblick

Persönlich hängt die ordnungsgemäße Verwendung der Scope-Funktion nur davon ab, ob Sie den Empfänger als Rückgabewert zurückgeben möchten oder nicht. Wenn das Schlüsselwort this danach kompliziert erscheint, werde ich es ordnungsgemäß verwenden, indem ich darauf verzichte.

scopefunction-selection.png

Diese Quelle

Recommended Posts

Mit Kotorin ―― 7. Scoping-Funktion
Frühling mit Kotorin ―― 1. SPRING INITIALIZR
Serverlose Funktion mit Micronaut
Feder mit Kotorin ―― 3. Auslassen von Wellenklammern aus der Funktion
Java zum Spielen mit Function
Frühling mit Kotorin --- 8. Aufbewahrungsschicht
Feder mit Kotorin --6 Asynchrone Verarbeitung
Feder mit Kotorin ―― 7. Serviceschicht
Anmeldefunktion mit Spring Security
Feder mit Kotorin --4 REST API Design
Implementierte Authentifizierungsfunktion mit Spring Security ②
Implementierte Authentifizierungsfunktion mit Spring Security ①
[Schienenentnahme] Erstellen Sie eine einfache Entnahmefunktion mit Schienen
Versuchen Sie, eine Anmeldefunktion mit Spring-Boot zu implementieren
Authentifizierungsfunktion mit Play Framework [Registrierung und Authentifizierung]
Erstellen Sie trotzdem eine Anmeldefunktion mit Rails
So implementieren Sie TextInputLayout mit Validierungsfunktion
Implementieren Sie die Paging-Funktion mit Spring Boot + Thymeleaf