Scope functions — шта су, врсте и примена у Котлину

Аутор: IT Sectr Објављено: 2026-06-23 Време читања: 8 мин

Scope functions у Котлину су пет функција стандардне библиотеке (let, run, with, apply, also) које извршавају блок кода у контексту објекта. Оне се разликују по начину приступа објекту (путем it или this) и повратној вредности (контекстни објекат или резултат ламбде). Према документацији Котлина (2026), правилан избор scope function смањује boilerplate код за 25–40%. Scope functions помажу у писању иницијализације, конфигурације и трансформације објеката у декларативном стилу.

Главно

  • Scope functions — пет функција Котлина (let, run, with, apply, also) за рад у контексту објекта
  • Контекст путем this — run, with, apply користе this, омогућавајући директно позивање метода објекта
  • Контекст путем it — let и also преносе објекат као параметар it са експлицитним именовањем
  • Повратак објекта — apply и also враћају контекстни објекат за ланчање позива
  • Повратак резултата — let, run и with враћају последњи израз ламбде

Шта су scope functions?

Scope functions (функције опсега) — скуп од пет функција (let, run, with, apply, also) уграђених у стандардну библиотеку Котлина. Свака од њих прима ламбду и привремено мења опсег видљивости тако да се унутар ламбде код извршава у контексту одређеног објекта. Ово елиминише понављање имена објекта при вишеструким позивима и групише повезане операције у један блок.

Две кључне карактеристике разликују scope functions: начин приступа контекстном објекту (путем this или it) и повратна вредност (сам контекстни објекат или резултат ламбде). Приступ путем this чини објекат имплицитним примаоцем — методе и својства се позивају без префикса. Приступ путем it преноси објекат као експлицитни параметар ламбде. Повратак објекта омогућава градњу ланаца, повратак резултата — доделу трансформисане вредности.

Историјски, scope functions су се појавиле као замена за класични образац Builder и привремене променљиве за иницијализацију. Уместо креирања засебне builder класе, програмер пише apply { својство1 = ...; својство2 = ... }. Ово смањује количину кода и чини иницијализацију читљивијом. У екосистему Котлина, scope functions се користе у свим оквирима и библиотекама као стандардни идиом језика.

Поређење scope functions: this vs it, повратак објекта vs резултат

Избор одговарајуће scope function одређују два питања: да ли желите да користите this или it за приступ објекту, и да ли желите да вратите сам објекат или резултат ламбде. Комбинација две бинарне карактеристике даје четири могуће варијанте, а with заузима посебно место као једина функција која није проширење.

ФункцијаПриступПовратакПроширење?Типичан сценарио
letitрезултат ламбдедаТрансформација, null провера
runthisрезултат ламбдедаИзрачунавање са контекстом
withthisрезултат ламбденеГруписање позива
applythisконтекстни објекатдаИницијализација својстава
alsoitконтекстни објекатдаСпоредни ефекти, логирање

За конфигурацију објекта без враћања нове вредности користите apply (приступ путем this) или also (приступ путем it). За израчунавање нове вредности на основу објекта користите let (приступ путем it) или run (приступ путем this). За груписање позива без ланчања користите with. Праћење ове шеме чини код предвидљивим за друге програмере упознате са Котлином.

apply и also: конфигурација са повратком објекта

apply — scope function која враћа контекстни објекат и омогућава приступ њему путем this. То је идеалан алат за иницијализацију својстава објекта након креирања. Унутар apply блока могуће је постављати својства без понављања имена објекта. Метода враћа сам објекат, што омогућава уграђивање apply у ланце или коришћење у иницијализаторима.

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
}

У листингу, apply конфигурише ServerConfig, приступајући својствима директно путем this (this изостављен). Без apply морало би се писати config.host = ..., config.port = ... — три понављајуће референце на исту променљиву. Повратак објекта омогућава чување резултата конфигурације у val config. also, за разлику од apply, преноси објекат путем it и погодан је за споредне ефекте.

kotlin
fun saveUser(user: User) {
    validate(user).also { result ->
        println("Резултат валидације: $result")
    }
    val savedUser = user.also {
        log("Saving user ${it.id}")
        database.save(it)
    }
}

У примеру, also се користи за логирање — враћајући оригинални објекат, извршава споредни ефекат (испис поруке) без измене објекта. Ово је ланац: validate(user) враћа User, also логира резултат и прослеђује корисника даље. also је такође користан за додавање елемената у колекције или отклањање грешака усред ланца трансформација.

let и run: трансформације и израчунавања

let — scope function која враћа резултат ламбде и преноси контекст путем it. То је основна функција за null-безбедне трансформације: ако је објекат nullable, комбинација ?.let { } ће извршити блок само при ненултој вредности. let се такође користи за ограничавање опсега видљивости привремених променљивих и map-сличне трансформације из једног типа у други.

kotlin
fun findUser(id: Int): User?

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

// let са трансформацијом колекције
val numbers = listOf("1", "2", "3")
val parsed = numbers.firstOrNull()?.let {
    it.toIntOrNull()
} ?: 0

У првом примеру, let се позива путем ?. — блок се извршава само ако је findUser вратио ненулту вредност. Ламбда прима user путем it (може се преименовати ради јасноће) и враћа форматирани стринг. Ако корисник није пронађен — Елвис оператор ?: даје подразумевану вредност. У другом примеру, let претвара стринг у број са потенцијалним null.

run — аналог let-а са приступом путем this, који враћа резултат ламбде. run је погодан за израчунавања где је потребан контекст објекта, али се враћа нова вредност. Позив run() без објекта (као run { ... }) ствара привремени опсег видљивости за променљиве. with — непроширење са приступом путем this, погодно за груписање позива без ланчања.

kotlin
// run као контекстуално израчунавање
val transformed = listOf(1, 2, 3).run {
    filter { it > 1 }.map { it * 10 }
}
println(transformed) // [20, 30]

// with за груписање позива
val info = with(StringBuilder()) {
    append("Name: ")
    append("Alice")
    toString()
}

У примеру, run на листи враћа резултат филтрирања и мапирања — саму трансформацију, а не листу. with прима StringBuilder као аргумент (не путем тачке) и унутра ради са this: append, append, toString. Резултат with — стринг info. Избор између run и with је често субјективан, али with је пожељнији када се објекат преноси из другог места без ланца позива.

with: контекст без проширења

with се разликује од осталих scope functions по томе што није функција-проширење. Она прима објекат као први аргумент, а ламбду као други. Унутар ламбде, објекат је доступан путем this. with је погодан за груписање позива метода објекта без чувања резултата или када је потребно привремено „ући” у контекст ради читања више својстава.

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 компоненте
with(TextView(context)) {
    text = "Hello"
    textSize = 18.0f
    setTextColor(Color.BLUE)
}

У првом примеру, with формира стринг summary, приступајући својствима user директно путем this. Без with морало би се писати „User ${user.name} has role ${user.role}” — вишеструко понављање user. У другом примеру, with групише конфигурацију TextView: сви методи и својства се позивају на једном објекту без понављања. Недостатак with — немогућност употребе у ланцу, јер није проширење и не враћа контекстни објекат.

Често постављана питања

Коју scope function одабрати за иницијализацију објекта?

Користите apply — враћа објекат и омогућава приступ путем this, омогућавајући постављање својстава без понављања имена објекта. also је погодан ако је потребан експлицитни параметар it ради разликовања од својстава објекта.

Чим се let разликује од run?

let преноси контекст путем it (експлицитни параметар), run — путем this (имплицитни прималац). let је погодан за null провере и трансформације, run — за израчунавања са контекстом. Обе враћају резултат ламбде.

Када применити with уместо apply?

with није проширење — прима објекат као аргумент. Користите with за груписање позива када ланац није потребан. apply — проширење које враћа објекат, погодно у иницијализаторима и builder обрасцима.

Може ли се једна scope function угнездити у другу?

Да, али будите опрезни са this — угнежђени this стварају забуну. Користите let или also са експлицитним именима за угнежђене контексте да бисте избегли двосмисленост при позивању спољашњег објекта.

Која scope function је најперформантнија?

Све scope functions су inline, па не стварају додатни overhead за анонимне класе. Разлика у перформансама између њих је занемарљива. Избор треба да се заснива на читљивости и конвенцијама, а не на брзини.

Резиме

  • Scope functions — пет inline функција Котлина (let, run, with, apply, also) за извршавање кода у контексту објекта
  • apply враћа контекстни објекат са приступом путем this — идеалан за иницијализацију својстава
  • also враћа контекстни објекат са приступом путем it — погодан за логирање и споредне ефекте
  • let враћа резултат ламбде са приступом путем it — основа за null-безбедне трансформације
  • run враћа резултат ламбде са приступом путем this — погодан за израчунавања са контекстом
  • with није проширење и враћа резултат ламбде — погодан за груписање позива без ланца
  • Комбинација карактеристика (this/it и повратак објекта/резултата) одређује избор scope function за сваки задатак

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође