Что вкладывается/не вкладывается пакеты в Scala 2.8?

В Scala 2.7 я мог записать:

package com.acme.bar

class Bar

.

package com.acme.foo

class Foo {
  new bar.Bar
}

Это не компилирует в Scala 2.8 - однако это делает:

package com.acme 
package bar

class Bar

.

package com.acme
package foo

class Foo {
  new bar.Bar
}
  1. Какова была мотивация для этого?
  2. Что точное означает относительно объема и видимости?
  3. Когда я должен использовать одну форму по другому?
22
задан retronym 14 May 2010 в 15:12
поделиться

3 ответа

В списках рассылки было несколько долгих обсуждений по этому поводу. См. этот поток для решения проблемы и этот поток для решения .

Что касается значения, только форма

package A
package B

откроет область для A , что сделает элементы A видимыми без префикса. Вы обычно используете эту форму, если ваш проект состоит из нескольких подпакетов, которые ссылаются друг на друга. С другой стороны, вы должны использовать форму

package A.B.C

, если вы хотите интегрировать C в иерархию пакетов и не собираетесь получать доступ к другим членам A или B напрямую. Типичный случай:

package net.myorg.myproject

Здесь вы не хотите быть уязвимыми для того, что кто-то еще определил пакет net.java, который будет затенять java корневого уровня. В Scala 2.7 этого можно было избежать, используя импорт _root_ . Но это некрасиво, и в целях безопасности вам придется делать это почти везде. Так что нынешнее решение намного лучше, ИМО.

18
ответ дан 29 November 2019 в 04:46
поделиться

Разве это не дает вам больше контроля над тем, что импортируется? Например, если были пакеты:

package com.acme.foo.client
package com.acme.client

А затем изнутри Foo , не возникла ли досадная двусмысленность относительно того, к какому клиенту идет ссылка? Например, если вы хотите импортировать подстановочный знак изнутри Foo :

class Foo {
  import client._ //what is being imported?
}

Это могло бы быть гораздо более проблематичным, если бы вместо клиента мы использовали пакет com.acme.java :

class Foo {
    val jul = new java.util.LinkedList //compile error; cannot find util
}
9
ответ дан 29 November 2019 в 04:46
поделиться

Спасибо за ответы! Позвольте мне добавить два небольших пункта, и готово!

Видимость

Разница между вложенными и невложенными пакетами относится только к области видимости. Видимость всегда основана на вложенных пакетах.

package A

private[A] trait Secret

Это работает:

package A
package B

trait AB extends Secret

То же самое:

package A.B

trait AB extends A.Secret

В обоих случаях структура интерпретируется как:

package A {
  trait Secret
  package B {
     //...
  }
}

Scoping

Сравните это с scoping , в котором вы можете себе представить это интерпретация для невложенных пакетов:

package A {
  private [A] trait Secret
}

package `A.B` {
   trait AB extends A.Secret

}

Смешивание и сопоставление

Вы можете произвольно смешивать и сопоставлять вложенные и невложенные пакеты:

package com.acme.project
package util.shazam
package blerg
13
ответ дан 29 November 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: