In Scala 2.7, I could write:
package com.acme.bar
class Bar
.
package com.acme.foo
class Foo {
new bar.Bar
}
This d开发者_StackOverflowoesn't compile in Scala 2.8 -- however this does:
package com.acme
package bar
class Bar
.
package com.acme
package foo
class Foo {
new bar.Bar
}
- What was the motivation for this?
- What is the precise meaning, with regards to scope and visibility?
- When should I use one form over the other?
There were several long discussions on the mailing lists about this. See this thread for the problem and this thread for the solution.
As to meaning, only the
package A
package B
form will open a scope for A
, which makes members of A
visible without prefix. You'd typically use this form if your project consists of several subpackages which refer to each other. On the other hand, you'd use the form
package A.B.C
If you want to integrate C
into the package hierarchy and do not intend to access other members of A
or B
directly. A typical case is
package net.myorg.myproject
Here, you do not want to be vulnerable to the possibility than somebody else has defined a
net.java package that would shadow the root level java. In Scala 2.7 you'd prevent that by using _root_
imports. But that's ugly, and to be safe you'd have to do this almost everywhere. So the present solution is much better, IMO.
Thanks for the answers so far! Let me add two small points, and we're done!
Visibility
The difference between nested and unnested packages only applies to scoping. Visibility is always based on nested packages.
package A
private[A] trait Secret
This works:
package A
package B
trait AB extends Secret
So does this:
package A.B
trait AB extends A.Secret
In both cases, the structure is interpreted as:
package A {
trait Secret
package B {
//...
}
}
Scoping
Compare this with scoping, in which you could imagine this interpretation for unnested packages:
package A {
private [A] trait Secret
}
package `A.B` {
trait AB extends A.Secret
}
Mix and Match
You can arbitrarily mix and match nested and unnested package:
package com.acme.project
package util.shazam
package blerg
Doesn't it give you more control over what is being imported? For example, if there were packages:
package com.acme.foo.client
package com.acme.client
And then from within Foo
, wasn't there an annoying ambiguity about which client
was being referred to? For example, if you want to do a wildcard import from within Foo
:
class Foo {
import client._ //what is being imported?
}
This might be much more problematic if, instead of client
, we had a package com.acme.java
:
class Foo {
val jul = new java.util.LinkedList //compile error; cannot find util
}
精彩评论