Packages, imports, and file-level declarations are at the core of the structure of any Kotlin project, and developers often face questions about organizing namespaces and visibility of functions.
Background: Kotlin, following the traditions of Java, supports a package system but adds the concept of file-level declarations, allowing the creation of functions and properties outside of classes, thus improving modularity and expressiveness of the code.
Problem: How to organize visibility and the entry point for functions, properties, and classes in the most convenient way, avoiding name conflicts, double imports, and excessive dependencies between parts of the project?
Solution:
Code example:
package utils import kotlin.math.* import model.User as UserModel fun sum(a: Int, b: Int) = a + b val PI2 = PI * 2
Key features:
Can different files with the same package name contain declarations with the same function/property names?
Yes, but it will lead to a name conflict at compile time if you do not use different names or aliases for imports. File-level declarations operate within the boundaries of the package.
Is it mandatory for the project's directory structure to reflect the package like in Java?
No, this is only recommended for code organization and maintenance convenience, but the compiler allows differences between paths and packages. However, issues with logging and modularity can arise when moving code or building through tools.
Can multiple packages be declared within a single .kt file?
No, only one package can be declared in a .kt file. Mixing packages leads to a compilation error.
All helper functions of different topics are located in one package utils, the file Utility.kt contains various business and technical methods:
Pros:
Cons:
Strictly follow conventions: each package reflects the domain area, file-level is used only for functions that do not belong to any class, aliases are used to eliminate duplication, each file has its own theme:
Pros:
Cons: