В 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
}
В списках рассылки было несколько долгих обсуждений по этому поводу. См. этот поток для решения проблемы и этот поток для решения .
Что касается значения, только форма
package A
package B
откроет область для A
, что сделает элементы A
видимыми без префикса. Вы обычно используете эту форму, если ваш проект состоит из нескольких подпакетов, которые ссылаются друг на друга. С другой стороны, вы должны использовать форму
package A.B.C
, если вы хотите интегрировать C
в иерархию пакетов и не собираетесь получать доступ к другим членам A
или B
напрямую. Типичный случай:
package net.myorg.myproject
Здесь вы не хотите быть уязвимыми для того, что кто-то еще определил пакет
net.java, который будет затенять java корневого уровня. В Scala 2.7 этого можно было избежать, используя импорт _root_
. Но это некрасиво, и в целях безопасности вам придется делать это почти везде. Так что нынешнее решение намного лучше, ИМО.
Разве это не дает вам больше контроля над тем, что импортируется? Например, если были пакеты:
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
}
Спасибо за ответы! Позвольте мне добавить два небольших пункта, и готово!
Разница между вложенными и невложенными пакетами относится только к области видимости. Видимость всегда основана на вложенных пакетах.
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 , в котором вы можете себе представить это интерпретация для невложенных пакетов:
package A {
private [A] trait Secret
}
package `A.B` {
trait AB extends A.Secret
}
Вы можете произвольно смешивать и сопоставлять вложенные и невложенные пакеты:
package com.acme.project
package util.shazam
package blerg