In Scala 2.7, I could write:
package com.acme.bar
class Bar
.
package com.acme.foo
class Foo {
new bar.Bar
}
This doesn'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
}
Package in Scala is a mechanism to encapsulate a group of classes, sub packages, traits and package objects. It basically provides namespace to put our code in a different files and directories. Packages is a easy way to maintain our code which prevents naming conflicts of members of different packages.
Since all packages are global in scope, nesting of packages is not supported. However, you can have two packages, one called A and another called A::B , to give an illusion of nesting.
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!
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 {
//...
}
}
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
}
You can arbitrarily mix and match nested and unnested package:
package com.acme.project
package util.shazam
package blerg
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With