在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
}
答案 0 :(得分:18)
关于这一点,在邮件列表上进行了几次长时间的讨论。 请参阅this thread for the problem和this thread for the solution。
至于含义,只有
package A
package B
表单将为A
打开一个范围,这使得A
的成员可以看不到前缀。如果您的项目包含多个相互引用的子包,则通常使用此表单。另一方面,您使用表格
package A.B.C
如果要将C
集成到包层次结构中,并且不打算直接访问A
或B
的其他成员。一个典型的案例是
package net.myorg.myproject
在这里,你不希望比其他人定义的那种容易受到攻击
net.java包会影响根级别java。在Scala 2.7中,您可以使用_root_
导入来阻止这种情况。但这很难看,为了安全起见,你几乎无处不在。所以目前的解决方案要好得多,IMO。
答案 1 :(得分:13)
感谢目前为止的答案!让我添加两个小点,我们就完成了!
嵌套和未嵌套包之间的区别仅适用于范围。 可见性始终基于嵌套包。
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 {
//...
}
}
将此与范围进行比较,您可以在其中想象对未使用的包进行此解释:
package A {
private [A] trait Secret
}
package `A.B` {
trait AB extends A.Secret
}
您可以随意混合和匹配嵌套和未嵌套的包:
package com.acme.project
package util.shazam
package blerg
答案 2 :(得分:9)
它不能让您更好地控制导入的内容吗?例如,如果有包:
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
}