Почему мой объект не является членом пакета <root>, если он находится в отдельном исходном файле?
У меня проблема с доступом к объекту, определенному в корневом пакете. Если у меня есть весь мой код в одном файле, он отлично работает, но когда я разбиваю его на два файла, я не могу его пропустить мимо компилятора.
Это отлично работает:
Все в одном файле с именем packages.scala
:
object Foo
val name = "Brian"
}
package somepackage {
object Test extends App {
println(Foo.name)
}
}
Свидетель:
$ scalac packages.scala
$ scala -cp . somepackage.Test
Brian
Но если я разделил код на два файла:
packages.scala
object Foo {
val name = "Brian"
}
packages2.scala
package somepackage {
object Test extends App {
println(Foo.name)
}
}
все сбой:
$ scalac packages.scala packages2.scala
packages2.scala:3: error: not found: value Foo
Итак, я пытаюсь сделать ссылку на Foo
absolute:
...
println(_root_.Foo.name)
...
Но это тоже не работает:
$ scalac packages.scala packages2.scala
packages2.scala:3: error: object Foo is not a member of package <root>
Если Foo
не является членом корневого пакета, где это на самом деле?
Ответы
Ответ 1
Я думаю, что это важная часть в спецификации:
Предполагается, что определения верхнего уровня за пределами упаковки вводятся в специальный пустой пакет. Этот пакет нельзя назвать и, следовательно, не может быть импортирован. Однако члены пустой упаковки видны друг другу без квалификации.
Источник Scala Ссылка §9.2 Пакеты.
Но не спрашивайте меня, почему это работает, если в packages2.scala
есть следующее:
object Dummy
package somepackage {
object Test extends App {
println(Foo.name)
}
}
Ответ 2
Foo является членом корневого пакета, но вы не можете ссылаться на него. Это общая вещь с языками JVM, (см. Как получить доступ к java-классам в пакете по умолчанию? для Groovy, Какой синтаксис для импорта класса в пакет по умолчанию в Java?). То же самое для Scala.
Из ответа Java:
Вы не можете импортировать классы из пакета по умолчанию. Вы должны избегать используя пакет по умолчанию, за исключением очень маленьких примеров программ.
Из спецификации языка Java:
Это ошибка времени компиляции для импорта типа из неназванного пакета.
Причина, по которой он работает в одном файле, состоит в том, что все доступно компилятору сразу, и компилятор справляется с ним. Я подозреваю, что это позволяет создавать сценарии.
Мораль истории: не используйте пакет по умолчанию, если вы не используете скрипты.