Scala 2.8 中的嵌套/非嵌套包是什么?

发布于 2024-09-01 02:56:58 字数 459 浏览 3 评论 0原文

在 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. 这样做的动机是什么?
  2. 关于范围和可见性,确切的含义是什么?
  3. 我什么时候应该使用一种形式而不是另一种形式?

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
}
  1. What was the motivation for this?
  2. What is the precise meaning, with regards to scope and visibility?
  3. When should I use one form over the other?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

荒岛晴空 2024-09-08 02:56:58

邮件列表上对此进行了多次长时间的讨论。
请参阅此线程解决问题此线程解决方案

至于意义,只有

package A
package B

表单才会为A打开一个范围,这使得A的成员在没有前缀的情况下可见。如果您的项目由多个相互引用的子包组成,您通常会使用此形式。另一方面,

package A.B.C

如果您想将 C 集成到包层次结构中,并且不打算访问 AB 的其他成员,则 可以使用以下形式直接。一个典型的情况是

package net.myorg.myproject

,您不希望容易受到其他人定义的可能性的影响
net.java 包将隐藏根级别 java。在 Scala 2.7 中,您可以通过使用 _root_ 导入来防止这种情况发生。但这很丑陋,而且为了安全起见,你必须在几乎所有地方都这样做。所以目前的解决方案要好得多,IMO。

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.

痴情换悲伤 2024-09-08 02:56:58

感谢到目前为止的回答!让我补充两个小点,我们就完成了!

可见

性 嵌套包和非嵌套包之间的区别仅适用于范围界定。 可见性始终基于嵌套包。

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

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
轻拂→两袖风尘 2024-09-08 02:56:58

它不会让您更好地控制导入的内容吗?例如,如果有包:

package com.acme.foo.client
package com.acme.client

然后从 Foo 内部,是否存在关于引用哪个 client 的恼人的歧义?例如,如果您想从 Foo 中进行通配符导入:

class Foo {
  import client._ //what is being imported?
}

如果我们使用 client 而不是 client,这可能会产生更多问题一个包com.acme.java

class Foo {
    val jul = new java.util.LinkedList //compile error; cannot find util
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文