Scope functions — mik ezek, típusai és alkalmazása Kotlinban

Szerző: IT Sectr Megjelenés: 2026-06-23 Olvasási idő: 8 perc

A scope functions Kotlinban a szabványos könyvtár öt függvénye (let, run, with, apply, also), amelyek egy kódblokkot egy objektum kontextusában hajtanak végre. Az objektumhoz való hozzáférés módjában (it vagy this segítségével) és a visszatérési értékben (kontextusobjektum vagy lambda eredménye) különböznek. A Kotlin dokumentáció (2026) szerint a scope function helyes megválasztása 25–40%-kal csökkenti a boilerplate kódot. Scope functions segítenek az objektumok inicializálásának, konfigurálásának és átalakításának deklaratív stílusban történő megírásában.

Főbb pontok

  • Scope functions — öt Kotlin függvény (let, run, with, apply, also) az objektum kontextusában végzett munkához
  • Kontextus this segítségével — run, with, apply a this-t használják, lehetővé téve az objektum metódusainak közvetlen meghívását
  • Kontextus it segítségével — let és also az objektumot it paraméterként adják át explicit elnevezéssel
  • Objektum visszaadása — apply és also visszaadják a kontextusobjektumot a hívások láncolásához
  • Eredmény visszaadása — let, run és with a lambda utolsó kifejezését adják vissza

Mik azok a scope functions?

Scope functions (hatókör függvények) — öt függvényből álló készlet (let, run, with, apply, also), amelyek a Kotlin szabványos könyvtárába vannak beépítve. Mindegyikük fogad egy lambdát, és ideiglenesen megváltoztatja a láthatósági hatókört úgy, hogy a lambdán belüli kód egy adott objektum kontextusában hajtódik végre. Ez elkerüli az objektum nevének ismétlését többszörös hívásoknál, és a kapcsolódó műveleteket egy blokkba csoportosítja.

Két kulcsfontosságú jellemző különbözteti meg a scope functions-t: a kontextusobjektumhoz való hozzáférés módja (this vagy it segítségével) és a visszatérési érték (maga a kontextusobjektum vagy a lambda eredménye). A this segítségével történő hozzáférés implicit fogadóvá teszi az objektumot — a metódusok és tulajdonságok előtag nélkül hívhatók. Az it segítségével történő hozzáférés explicit paraméterként adja át az objektumot a lambdának. Az objektum visszaadása lehetővé teszi láncok építését, az eredmény visszaadása pedig az átalakított érték hozzárendelését.

Történelmileg a scope functions a klasszikus Builder minta és az inicializáláshoz használt ideiglenes változók helyettesítőjeként jelentek meg. Külön builder osztály létrehozása helyett a programozó ezt írja: apply { tulajdonság1 = ...; tulajdonság2 = ... }. Ez csökkenti a kód mennyiségét és olvashatóbbá teszi az inicializálást. A Kotlin ökoszisztémában a scope functions minden keretrendszerben és könyvtárban a nyelv szabványos idiómájaként használatos.

Scope functions összehasonlítása: this vs it, objektum vs eredmény

A megfelelő scope function kiválasztását két kérdés határozza meg: szeretné-e a this vagy az it használni az objektum eléréséhez, és szeretné-e magát az objektumot vagy a lambda eredményét visszaadni. Két bináris jellemző kombinációja négy lehetséges változatot ad, a with pedig különleges helyet foglal el, mint az egyetlen függvény, amely nem kiterjesztés.

FüggvényHozzáférésVisszaadásKiterjesztés?Tipikus forgatókönyv
letitlambda eredményeigenÁtalakítás, null ellenőrzés
runthislambda eredményeigenSzámítás kontextussal
withthislambda eredményenemHívások csoportosítása
applythiskontextusobjektumigenTulajdonságok inicializálása
alsoitkontextusobjektumigenMellékhatások, naplózás

Objektum konfigurálásához új érték visszaadása nélkül használja az apply-t (hozzáférés this segítségével) vagy az also-t (hozzáférés it segítségével). Új érték kiszámításához az objektum alapján használja a let-et (hozzáférés it segítségével) vagy a run-t (hozzáférés this segítségével). Hívások csoportosításához láncolás nélkül használja a with-t. E séma követése kiszámíthatóvá teszi a kódot más, Kotlinban járatos fejlesztők számára.

apply és also: konfiguráció objektum visszaadásával

apply — scope function, amely visszaadja a kontextusobjektumot, és this segítségével biztosít hozzáférést. Ez az ideális eszköz az objektum tulajdonságainak létrehozás utáni inicializálásához. Az apply blokkon belül a tulajdonságok beállíthatók az objektum nevének ismétlése nélkül. A metódus magát az objektumot adja vissza, lehetővé téve az apply beágyazását láncokba vagy használatát inicializálókban.

kotlin
data class ServerConfig(
    var host: String = "localhost",
    var port: Int = 8080,
    var useTls: Boolean = false
)

val config = ServerConfig().apply {
    host = "api.example.com"
    port = 443
    useTls = true
}

A listában apply konfigurálja a ServerConfig-ot, közvetlenül a this segítségével érve el a tulajdonságokat (this elhagyva). Apply nélkül config.host = ..., config.port = ... kellene írni — három ismétlődő hivatkozás ugyanarra a változóra. Az objektum visszaadása lehetővé teszi a konfiguráció eredményének elmentését a val config változóba. also az apply-pal ellentétben az it segítségével adja át az objektumot, és mellékhatásokhoz alkalmas.

kotlin
fun saveUser(user: User) {
    validate(user).also { result ->
        println("Ellenőrzés eredménye: $result")
    }
    val savedUser = user.also {
        log("Saving user ${it.id}")
        database.save(it)
    }
}

A példában also naplózásra használatos — az eredeti objektum visszaadásával mellékhatást hajt végre (üzenet kiírása) az objektum módosítása nélkül. Ez egy lánc: a validate(user) visszaadja a User-t, az also naplózza az eredményt és továbbadja a felhasználót. Az also hasznos továbbá elemek gyűjteményekhez adásához vagy hibakereséshez egy átalakítási lánc közepén.

let és run: átalakítások és számítások

let — scope function, amely visszaadja a lambda eredményét, és a kontextust az it segítségével adja át. Ez az elsődleges függvény null-biztos átalakításokhoz: ha az objektum nullable, a ?.let { } kombináció csak nem null érték esetén hajtja végre a blokkot. A let az ideiglenes változók láthatósági hatókörének korlátozására és map-szerű átalakításokra is használatos egyik típusból a másikba.

kotlin
fun findUser(id: Int): User?

val displayName = findUser(42)?.let { user ->
    "${user.name} (${user.email})"
} ?: "Unknown user"

// let gyűjteményátalakítással
val numbers = listOf("1", "2", "3")
val parsed = numbers.firstOrNull()?.let {
    it.toIntOrNull()
} ?: 0

Az első példában let a ?. segítségével hívódik meg — a blokk csak akkor hajtódik végre, ha a findUser nem null értéket adott vissza. A lambda az it segítségével fogadja a user-t (átnevezhető az érthetőség kedvéért) és visszaad egy formázott karakterláncot. Ha a felhasználó nem található — az Elvis operátor ?: alapértelmezett értéket ad. A második példában a let egy karakterláncot alakít át számmá potenciális null értékkel.

run — a let megfelelője this segítségével történő hozzáféréssel, amely visszaadja a lambda eredményét. A run kényelmes olyan számításokhoz, ahol az objektum kontextusa szükséges, de új érték kerül visszaadásra. A run() hívás objektum nélkül (mint run { ... }) ideiglenes láthatósági hatókört hoz létre változók számára. with — nem kiterjesztés this segítségével történő hozzáféréssel, alkalmas hívások láncolás nélküli csoportosítására.

kotlin
// run kontextusvezérelt számításként
val transformed = listOf(1, 2, 3).run {
    filter { it > 1 }.map { it * 10 }
}
println(transformed) // [20, 30]

// with hívások csoportosításához
val info = with(StringBuilder()) {
    append("Name: ")
    append("Alice")
    toString()
}

A példában a listán run visszaadja a szűrés és map-elés eredményét — magát az átalakítást, nem a listát. A with a StringBuilder-t argumentumként fogadja (nem pont segítségével) és belül a this-szel dolgozik: append, append, toString. A with eredménye — az info karakterlánc. A run és with közötti választás gyakran szubjektív, de a with előnyösebb, ha az objektum máshonnan kerül átadásra hívási lánc nélkül.

with: kontextus kiterjesztés nélkül

with abban különbözik a többi scope functions-tól, hogy nem kiterjesztési függvény. Első argumentumként az objektumot, másodikként a lambdát fogadja. A lambdán belül az objektum a this segítségével érhető el. A with kényelmes az objektum metódushívásainak csoportosításához az eredmény mentése nélkül, vagy amikor ideiglenesen „be kell lépni” a kontextusba több tulajdonság olvasásához.

kotlin
val user = User("Alice", "alice@example.com", "Admin")

val summary = with(user) {
    "User $name has role $role and email $email"
}
println(summary)

// with UI komponens inicializálásához
with(TextView(context)) {
    text = "Hello"
    textSize = 18.0f
    setTextColor(Color.BLUE)
}

Az első példában with képezi a summary karakterláncot, közvetlenül a this segítségével érve el a user tulajdonságait. With nélkül „User ${user.name} has role ${user.role}” kellene írni — a user többszörös ismétlése. A második példában a with csoportosítja a TextView konfigurációját: az összes metódus és tulajdonság egy objektumon hívódik meg ismétlés nélkül. A with hátránya — nem használható láncban, mivel nem kiterjesztés és nem adja vissza a kontextusobjektumot.

Gyakran Ismételt Kérdések

Melyik scope function-t válasszam objektum inicializálásához?

Használja az apply-t — visszaadja az objektumot és this segítségével biztosít hozzáférést, lehetővé téve a tulajdonságok beállítását az objektum nevének ismétlése nélkül. Az also akkor megfelelő, ha explicit it paraméter szükséges az objektum tulajdonságaitól való megkülönböztetéshez.

Miben különbözik a let a run-tól?

let a kontextust az it segítségével adja át (explicit paraméter), a run — a this segítségével (implicit fogadó). A let null ellenőrzésekhez és átalakításokhoz alkalmas, a run — kontextussal végzett számításokhoz. Mindkettő visszaadja a lambda eredményét.

Mikor használjam a with-t az apply helyett?

with nem kiterjesztés — az objektumot argumentumként fogadja. Használja a with-t hívások csoportosításához, ha nincs szükség láncra. apply — kiterjesztés, amely visszaadja az objektumot, kényelmes inicializálókban és builder mintákban.

Beágyazható egy scope function egy másikba?

Igen, de óvatosan a this-szel — az egymásba ágyazott this-ek zavart okoznak. Használjon let-et vagy also-t explicit nevekkel az egymásba ágyazott kontextusokhoz, hogy elkerülje a kétértelműséget a külső objektumra való hivatkozáskor.

Melyik scope function a legteljesítményesebb?

Minden scope function inline, így nem hoznak létre többletterhelést névtelen osztályok számára. A teljesítménybeli különbség közöttük elhanyagolható. A választásnak az olvashatóságon és konvenciókon kell alapulnia, nem a sebességen.

Összefoglalás

  • Scope functions — öt inline Kotlin függvény (let, run, with, apply, also) kód végrehajtásához objektum kontextusában
  • apply visszaadja a kontextusobjektumot this segítségével történő hozzáféréssel — ideális tulajdonságok inicializálásához
  • also visszaadja a kontextusobjektumot it segítségével történő hozzáféréssel — alkalmas naplózásra és mellékhatásokra
  • let visszaadja a lambda eredményét it segítségével történő hozzáféréssel — a null-biztos átalakítások alapja
  • run visszaadja a lambda eredményét this segítségével történő hozzáféréssel — kényelmes kontextussal végzett számításokhoz
  • with nem kiterjesztés és visszaadja a lambda eredményét — alkalmas hívások lánc nélküli csoportosítására
  • A jellemzők kombinációja (this/it és objektum/eredmény visszaadása) határozza meg a scope function kiválasztását minden feladathoz

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is