Подтвердить что ты не робот

Почему мой объект не является членом пакета <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 не является членом корневого пакета, где это на самом деле?

4b9b3361

Ответ 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:

Это ошибка времени компиляции для импорта типа из неназванного пакета.

Причина, по которой он работает в одном файле, состоит в том, что все доступно компилятору сразу, и компилятор справляется с ним. Я подозреваю, что это позволяет создавать сценарии.

Мораль истории: не используйте пакет по умолчанию, если вы не используете скрипты.