Что такое вложенные / не вложенные пакеты в Scala 2.8? - PullRequest
22 голосов
/ 14 мая 2010

В 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. Когда я должен использовать одну форму поверх другой?

Ответы [ 3 ]

18 голосов
/ 14 мая 2010

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

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

package A
package B
Форма

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

package A.B.C

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

package net.myorg.myproject

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

13 голосов
/ 14 мая 2010

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

Видимость

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

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
9 голосов
/ 14 мая 2010

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

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

А затем изнутри Foo, не было ли раздражающей двусмысленности, о которой упоминалось client? Например, если вы хотите сделать подстановочный знак импорт из Foo:

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

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

class Foo {
    val jul = new java.util.LinkedList //compile error; cannot find util
}
...