1

I have two files:

Main.kt:

package A

fun gg1() = "hello"

Main2.kt:

package B
import A.gg1

fun gg2() = gg1()

Trying to compile the code:

iv@LAPTOP:~$ tree .
.
├── A
│   └── Main.kt
└── B
    └── Main2.kt

2 directories, 2 files
iv@LAPTOP:~$ kotlinc B/Main2.kt
B/Main2.kt:3:8: error: unresolved reference: A
import A.gg1
       ^
B/Main2.kt:5:13: error: unresolved reference: gg1
fun gg2() = gg1()
            ^
iv@LAPTOP:~$

Why do i get this error and how to fix it ?

VanechikSpace
  • 265
  • 2
  • 9

1 Answers1

1

You're only passing B/Main2.kt to kotlinc. You need to pass the other file too if you want the compiler to be aware of its existence.

Imports don't work as file/path references: the import A.gg1 doesn't tell the compiler to look for A/Main.kt (how would it know the file name?). There is no technical relation between the package names and the paths of the files, just a convenient convention.

In fact, imports are mostly syntax sugar to avoid using fully qualified names within the code (so the code itself looks a bit simpler), but they are not necessary per se, and you could just use declarations without imports if you wanted to (except in some specific cases).

Maybe this related question could shed some light too: How does import find the file path in Kotlin?

Joffrey
  • 32,348
  • 6
  • 68
  • 100
  • “imports are mostly syntax sugar to avoid using fully qualified names” — exactly! This line could be highlighted. (It's the same in Java. This differs from languages like C, where `#include` _does_ tell the compiler to look for a file.) – gidds Feb 12 '23 at 18:59
  • Thanks for the reply. Can you explain one thing to me ? In java, class file name matches actual class name. So when we run jvm, a class can be found by an import. But a function in kotlin is compiled into a class file that has a name which is different from the function name, and it still can be found at runtime. How ? – VanechikSpace Feb 14 '23 at 12:18
  • 1
    Just to clarify, imports don't exist at runtime. They are resolved by the compiler to find the declarations, then the bytecode just uses fully qualified names. Now, since Java doesn't have top-level functions, Kotlin compiles top-level functions as methods of a class. The name of that class is the name of the file + the `Kt` suffix, but that is not really relevant here. There is no bytecode referencing the top-level function directly, the Kotlin compiler uses the generated class name when referencing the function in the bytecode, so it knows it on both sides. – Joffrey Feb 14 '23 at 12:31