llms.txt: machine-readable documentation index. Markdown version of this page is also available.

Kotlin 语言参考文档 中文版 Help

上下文参数(Context Parameter)

上下文参数(Context Parameter) 允许函数和属性声明在周围上下文(Surrounding Context)中隐含可用的依赖项.

使用上下文参数, 在一组函数调用中, 你就不需要手动的反复传递那些共用而且极少变更的值, 例如服务或依赖项.

要对属性和函数声明上下文参数, 请使用 context 关键字, 之后是参数列表, 每个参数声明为 name: Type. 下面是一个示例, 依赖于 UserService 接口:

// UserService 定义上下文中需要的依赖项 interface UserService { fun log(message: String) fun findUserById(id: Int): String } // 声明一个带有上下文参数的函数 context(users: UserService) fun outputMessage(message: String) { // 使用上下文中的 log users.log("Log: $message") } // 声明一个带有上下文参数的属性 context(users: UserService) val firstUser: String // 使用上下文中的 findUserById get() = users.findUserById(1) fun main() { val users = object : UserService { override fun log(message: String) { println(message) } override fun findUserById(id: Int): String { return "User $id" } } context(users) { outputMessage("Looking up the first user") println(firstUser) // 输出结果为: User 1 } }

当你不需要直接引用上下文参数时, 可以使用 _ 作为它的名称. 匿名的上下文参数仍然可以满足被调用函数所要求的上下文参数, 但你不能通过名称访问它. 要明确的访问它的值, 请使用 contextOf<T>():

// 使用 "_" 作为上下文参数名称 context(_: UserService) fun logWelcome() { // 匿名参数满足了 outputMessage() 需要的 UserService 上下文参数 outputMessage("Welcome!") // 明确获取 UserService 值 contextOf<UserService>().log("Hi!") }

上下文参数的解析

Kotlin 通过在当前的范围(Scope) 中搜索匹配的上下文值, 在调用端解析上下文参数. Kotlin 会根据它们的类型进行匹配. 如果在同一个范围层级存在多个兼容的值, 编译器会报告歧义:

// UserService 定义上下文中需要的依赖项 interface UserService { fun log(message: String) } // 声明一个带有上下文参数的函数 context(users: UserService) fun outputMessage(message: String) { users.log("Log: $message") } fun main() { // 实现 UserService val serviceA = object : UserService { override fun log(message: String) = println("A: $message") } // 实现 UserService val serviceB = object : UserService { override fun log(message: String) = println("B: $message") } // 在调用端, serviceA 和 serviceB 都匹配期望的 UserService 类型 context(serviceA, serviceB) { // 这会导致歧义错误 outputMessage("This will not compile") } }

明确的传递上下文参数

当多个函数重载的区别仅仅只是上下文参数不同, 如果存在多个匹配的上下文值, 那么函数调用就会发生歧义.

为了解决这种歧义, 请在调用处明确指定上下文参数:

class EmailSender class SmsSender context(emailSender: EmailSender) fun sendNotification() { println("Sent email notification") } context(smsSender: SmsSender) fun sendNotification() { println("Sent SMS notification") } context(defaultEmailSender: EmailSender, defaultSmsSender: SmsSender) fun notifyUser() { // 选择使用 EmailSender 上下文参数的重载函数 sendNotification(emailSender = defaultEmailSender) // 选择使用 SmsSender 上下文参数的重载函数 sendNotification(smsSender = defaultSmsSender) }

你也可以使用明确的上下文参数, 在某些函数调用中减少嵌套:

  • 对单个调用, 使用明确的上下文参数, 可以让调用更加易读.

  • 如果多个调用使用相同的上下文参数, 请使用 context() 函数.

这个功能是 实验性功能. 要表示使用者同意(Opt-in), 请向你的构建脚本文件添加以下编译器选项:

kotlin { compilerOptions { freeCompilerArgs.add("-Xexplicit-context-arguments") } }
<build> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <configuration> <args> <arg>-Xexplicit-context-arguments</arg> </args> </configuration> </plugin> </plugins> </build>

限制

上下文参数还在不断改进中, 目前的一些限制包括:

  • 构造器不能声明上下文参数.

  • 上下文参数的属性不能拥有后端域变量(Backing Field), 也不能拥有初始化器.

  • 带上下文参数的属性 不能使用委托.

尽管存在这些限制, 上下文参数通过简化依赖项注入, 改进 DSL 设计, 以及范围操作, 简化了依赖的管理.

2026/10/11