在Scala 2.10中导入类型时的奇怪行为

在Scala 2.10中导入类型时的奇怪行为,scala,compiler-construction,sbt,scala-2.10,Scala,Compiler Construction,Sbt,Scala 2.10,今天我清除了.ivy缓存并清理了项目输出目标。从那时起,当使用SBT运行测试或在Scala IDE中编辑时,我的行为变得非常奇怪 鉴于以下情况: package com.abc.rest import com.abc.utility.IdTLabel 我将得到以下错误: object utility is not a member of package com.abc.rest.com.abc 请注意,com.abc重复了两次,因此编译器在执行导入时似乎使用了当前包的上下文(可能应该这样做

今天我清除了.ivy缓存并清理了项目输出目标。从那时起,当使用SBT运行测试或在Scala IDE中编辑时,我的行为变得非常奇怪

鉴于以下情况:

package com.abc.rest

import com.abc.utility.IdTLabel
我将得到以下错误:

object utility is not a member of package com.abc.rest.com.abc
请注意,
com.abc
重复了两次,因此编译器在执行导入时似乎使用了当前包的上下文(可能应该这样做,但我以前从未注意到)

此外,如果我试图从
com.abc.rest
中的任何位置访问包
com.abc
中的类(即使使用完整路径),编译器也会抱怨找不到该类型

似乎只有当我尝试包含来自父包的文件时,才会出现错误。我确实觉得奇怪的是,我的代码过去是可以工作的。它只是在我清理了我的项目和我的常春藤缓存之后才开始发生的,所以可能编译器的更高版本比上一版本更严格

我很想知道我做错了什么,或者我如何解决这个问题

更新:

通过首先导入父类,然后定义当前包,问题就解决了:

import com.abc.utility.IdTLabel
import com.abs._

package com.abc.rest {
 // Define classes belonging to com.abc.rest here
}
所以这是可行的,但我仍然很想知道为什么地球上的另一种方式起作用,然后停止工作,以及我到底如何修复它。我看得很清楚,在父包的任何地方都找不到名为com的包、对象或特征

与工作表相关的更新:

属于同一个包的Scala工作表共享相同的范围,这听起来很明显,但事实并非如此。工作表不是沙盒状的——它们可以看到项目,项目也可以看到它们。因此,您在工作表文件中创建的所有“测试”对象、特征和类也将在项目的其余部分可见

我有这么多的工作表,我甚至没有试着去看问题出在哪里。我只是简单地将他们全部转移到他们自己的包中,就像变魔术一样,问题消失了

因此,今天的经验教训是:如果你在工作表内创建内容,那么从工作表外就可以看到。

无论如何,这些新发现的知识会派上用场,这意味着任何“有趣”的东西都可以在工作表中构建、监控和调整,而项目的其他部分实际上可以使用它。其实挺酷的


想一想
sbt clean
和清理后的常春藤缓存如何突出显示以前隐藏的问题仍然很有趣,但是,嘿,这是另一回事….

如果包名冲突,可能会有一条自定义错误消息。查看指定完整路径是否可以通过从
\uuuuu根目录\uuuu
开始解决问题。例如,
import\uuuuu root\uuuuu.com.foo.bar.\uu

如果包名冲突,则可能会出现一条自定义错误消息。查看指定完整路径是否可以通过从
\uuuuu根目录\uuuu
开始解决问题。例如,
import\uuuuu root\uuuuu.com.foo.bar.\uu

(应JacobusR的要求,我对我先前的评论做出了正确的回答)

如果您在包
com.abc.rest.com
中定义了某些类/特征/对象,则可能会发生这种情况。只要package
com.abc.rest.com
存在,并且假设您在package
com.abc.rest
中,
com
将指定
com.abc.rest.com
,而不是
\u root\u.com
。最快的(但不是决定性的)检查方法,甚至不扫描源文件,是在“com/abc/rest/com”子文件夹中查找任何.class文件

特别是,如果您的任何文件具有重复的包定义(如package
com.abc.rest;package com.abc.rest;…
),则会出现这种行为。如果在发生错误的同一个文件中的某个地方有此duplicate package子句,您甚至不会看到.class文件有任何可疑之处,因为编译文件时的失败将阻止为文件中的任何类定义生成.class文件

最后一点有用的信息是,当您发现scala工作表没有沙盒时,您在工作表中定义的内容会影响项目的代码(而不仅仅是项目的代码会影响工作表)。因此,工作表中重复的package子句很可能会导致出现错误。

(应JacobusR的要求,我将根据我先前的评论做出正确的回答)

如果您在包
com.abc.rest.com
中定义了某些类/特征/对象,则可能会发生这种情况。只要package
com.abc.rest.com
存在,并且假设您在package
com.abc.rest
中,
com
将指定
com.abc.rest.com
,而不是
\u root\u.com
。最快的(但不是决定性的)检查方法,甚至不扫描源文件,是在“com/abc/rest/com”子文件夹中查找任何.class文件

特别是,如果您的任何文件具有重复的包定义(如package
com.abc.rest;package com.abc.rest;…
),则会出现这种行为。如果在发生错误的同一个文件中的某个地方有此duplicate package子句,您甚至不会看到.class文件有任何可疑之处,因为编译文件时的失败将阻止为文件中的任何类定义生成.class文件


最后一点有用的信息是,当您发现scala工作表没有沙盒时,您在工作表中定义的内容会影响项目的代码(而不仅仅是项目的代码会影响工作表)。因此,工作表中重复的package子句很可能会导致出现错误。

能否检查package
com.abc.rest.com
中是否未定义任何类/特征/对象?只要包
com.abc.rest。