Когда я должен использовать специальный идентификатор Scala `package`? - PullRequest
10 голосов
/ 05 июля 2011

В Scala вы можете определить объекты пакета . Таким образом, кажется, что вы можете получить доступ к этому объекту пакета, написав имя пакета, а затем `package`:

// file package.scala in src/com

package com
package object test {
  val Version = 2
}

// file Test.scala in src/test

package test
object Test {
  def main(args: Array[String]) {
    val p = com.test.`package`          // get ref on package object
    val v1 = com.test.`package`.Version // (1) get val
    val v2 = com.test.Version           // (2) get val
  }
}

В чем разница между (1) и (2)? В некоторых случаях мне приходилось писать дополнительные `package` для запуска моего кода. Должна ли быть разница или это ошибка компилятора?

Кроме того, что делает, например, эта строка означает, что в Predef.scala?

scala.`package`   // to force scala package object to be seen.

Ответы [ 4 ]

4 голосов
/ 05 июля 2011

Просто слепое предположение: линия

scala.`package`

приводит к простому getstatic (код объекта пакета), за которым следует pop. Поэтому он ничего не делает, кроме инициализации объекта пакета, если он еще не был инициализирован ранее.

Так что я предполагаю, что в Predef.scala вы не можете быть уверены (или, возможно, определенно, что этого не произошло), что объект пакета уже был инициализирован. Большинство других модулей могут неявно зависеть от загрузки Predef, поэтому эти модули нельзя просто инициализировать вслепую. Поэтому необходимо убедиться в этом, включив модуль / пакет / объект явно в Predef. То же самое сделано для модуля List и StringBuilder. Так что это может быть просто порядок инициализации.

3 голосов
/ 05 июля 2011

Нет разницы между (1) и (2) в вашем коде.Объект пакета позволяет записать его как (2).Но вы все равно можете написать как (1).

Я могу только представить, что случаи, когда вам приходилось писать package в вашем коде, должны иметь отношение к вашей среде разработки (Eclipse / Scala plugin)?) ожидая, что класс с именем "package" будет происходить из источника с именем "package.scala", а не из "test.scala".Можете ли вы воспроизвести случаи, когда у вас было , чтобы написать package?

Мне также любопытно, каков эффект этой строки в Predef.

2 голосов
/ 05 июля 2011

Насколько я понимаю, объекты пакета (представленные в Scala 2.8) означают, что все, что объявлено внутри них, автоматически попадает в область действия другого кода в том же пакете.Таким образом, объект пакета в Predef.scala содержит вещи, импортированные в область Scala верхнего уровня.Мартин Одерски, создатель Scala, написал хорошее введение в них об Artima год назад.

1 голос
/ 05 июля 2011

Слово package является зарезервированным ключевым словом в Scala.Однако это имя (идентификатор) объектов пакета.Поэтому, если вам нужен прямой доступ к объекту пакета, вам нужно использовать обратные кавычки, чтобы «экранировать» слово package.

Следующее определение эквивалентно тому, которое вы опубликовали в своем вопросе:

// file package.scala in src/com
package com.test
object `package` {
  val Version = 2
}

Более того, строка в Predef.scala

scala.`package`   // to force scala package object to be seen.

позволяет напрямую обращаться к объекту пакета, как к любому другому объекту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...