Какие вложенные/неактивные пакеты в 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
В списках рассылки было несколько длительных обсуждений.
См. этот поток для проблемы и этот поток для решения.
Что касается значения, то только
package A
package B
Форма откроет область для A
, что делает элементы A
видимыми без префикса. Обычно вы используете эту форму, если ваш проект состоит из нескольких подпакетов, которые ссылаются друг на друга. С другой стороны, вы должны использовать форму
package A.B.C
Если вы хотите интегрировать C
в иерархию пакетов и не намереваться напрямую обращаться к другим членам A
или B
. Типичный случай
package net.myorg.myproject
Здесь вы не хотите быть уязвимым для возможности, чем кто-либо другой определил
net.java, который затеняет уровень java уровня корня. В Scala 2.7 вы можете предотвратить это с помощью импорта _root_
. Но это уродливо, и, чтобы быть в безопасности, вам придется делать это почти везде. Таким образом, настоящее решение намного лучше, ИМО.
Ответ 2
Спасибо за ответы! Позвольте мне добавить две небольшие точки, и мы закончили!
Видимость
Разница между вложенными и неустановленными пакетами применяется только к области охвата. Видимость всегда основана на вложенных пакетах.
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
Ответ 3
Разве это не дает вам больше контроля над тем, что импортируется? Например, если были пакеты:
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
}