Kotlin 文件关键字
最后修改于 2025 年 4 月 19 日
Kotlin 的 file 关键字用于指定顶级声明的可见性修饰符。它控制对同一文件内声明的访问。本教程通过实际例子探讨了文件级可见性。
基本定义
Kotlin 中的 file
可见性修饰符使声明仅在同一源文件中可见。对于顶级声明,它比 internal
更严格,但比 private
宽松。
基本的文件私有可见性
file
关键字将可见性限制为当前文件。这对于不应在外部公开的辅助函数或类很有用。
package com.zetcode.utils file fun calculateSquare(x: Int): Int { return x * x } fun publicCalculateCube(x: Int): Int { return x * x * x } fun main() { println(calculateSquare(5)) // Accessible: 25 println(publicCalculateCube(3)) // Accessible: 27 }
在这里,calculateSquare
是文件私有的,只能在 Utils.kt 中使用。publicCalculateCube
可从其他文件访问。两者都可以在同一文件中的 main 函数中访问。
文件私有类
类也可以使用 file
修饰符标记为文件私有。这对于不应泄露到文件外部的实现细节很有用。
package com.zetcode.db file class DatabaseConnection(private val url: String) { fun connect() = println("Connected to $url") } fun createConnection(): DatabaseConnection { return DatabaseConnection("jdbc:mysql:///mydb") } fun main() { val conn = createConnection() conn.connect() // Works within same file }
DatabaseConnection
类仅在 Database.kt 中可见。createConnection
函数可以返回它,因为它们在同一个文件中。外部文件无法直接创建 DatabaseConnection
实例。
文件私有属性
顶级属性可以是文件私有的,以便在文件内共享状态,同时将其对其他文件隐藏。这对于模块级常量很有用。
package com.zetcode.config file const val MAX_RETRIES = 3 const val TIMEOUT = 5000L fun shouldRetry(attempt: Int): Boolean { return attempt < MAX_RETRIES } fun main() { println(shouldRetry(2)) // true println("Timeout: $TIMEOUT") // 5000 }
MAX_RETRIES
是文件私有的,而 TIMEOUT
是 public 的。两者都可以在 Config.kt 中访问,但只有 TIMEOUT
可以从其他文件访问。这控制了哪些实现细节被公开。
文件私有扩展函数
扩展函数可以是文件私有的,以限制其范围。这可以防止用仅在本地需要的扩展污染全局命名空间。
package com.zetcode.utils file fun String.encrypt(): String { return this.reversed() } fun String.publicEncrypt(): String { return encrypt() // Can call file-private function } fun main() { val secret = "password".encrypt() // Works println(secret) // Output: drowssap }
encrypt
扩展仅在 StringUtils.kt 中可用。publicEncrypt
可以在内部使用它。这种模式可以防止辅助扩展对其他文件可见,同时仍然可以在内部重复使用。
文件私有接口
接口可以是文件私有的,以将其实现限制为当前文件。这对于组件之间的内部约定很有用。
package com.zetcode.logging file interface Logger { fun log(message: String) } class ConsoleLogger : Logger { override fun log(message: String) { println("[LOG] $message") } } fun createLogger(): Logger { return ConsoleLogger() } fun main() { val logger = createLogger() logger.log("Test message") // [LOG] Test message }
Logger
接口仅在 Logger.kt 中可见。外部文件可以使用 createLogger
但不能直接实现 Logger
。这强制执行创建记录器的受控方式。
文件私有伴生对象
伴生对象成员可以是文件私有的,以便在类方法之间共享实现细节,同时将其对其他文件隐藏。
package com.zetcode.utils class IdGenerator { companion object { file var counter = 0 file fun nextId() = ++counter } fun generate(): Int { return nextId() // Can access file-private members } } fun main() { val gen = IdGenerator() println(gen.generate()) // 1 println(gen.generate()) // 2 }
counter
和 nextId
是文件私有的,但可被所有 IdGenerator
方法访问。这维护了状态,同时防止外部修改。每次调用 generate
都会增加计数器。
文件私有和内部可见性
当比较 file
和 internal
可见性时,file
更严格。internal
使声明对整个模块可见。
package com.zetcode.visibility file val filePrivate = "File private" internal val moduleVisible = "Module visible" fun printValues() { println(filePrivate) // Accessible println(moduleVisible) // Accessible } fun main() { printValues() }
filePrivate
仅在 Visibility.kt 中可见,而 moduleVisible
可以从同一模块中的任何文件访问。两者都可以在声明它们的文件中访问。
文件私有声明的最佳实践
- 隐藏实现细节:对不应在文件外部公开的辅助程序使用文件私有。
- 减少命名空间污染:使特定于文件的扩展和实用程序保持文件私有。
- 谨慎地共享状态:使用文件私有属性来表示不应在外部修改的文件级状态。
- 记录文件私有 API:即使它们不是 public 的,也要为维护人员记录它们。
- 考虑备选方案:对于真正私有的声明,请在类或对象中使用
private
。
来源
本教程深入探讨了 Kotlin 的 file
可见性修饰符。我们探讨了各种用例,包括函数、类、属性和接口。正确使用文件私有可见性有助于创建干净、模块化的代码,并对实现细节进行良好控制的访问。
作者
列出 所有 Kotlin 教程。