与一个简单的Scala打包示例的混淆
在Scala中打包类和导入包的问题上,我一直感到困惑。让我从一对简单的源文件开始: 文件:a/a.scala 文件:a/b/b.scala 使用 在A.scala中,使用scalac编译可以毫无怨言地使用上述任何一种导入 尝试在REPL中加载这些文件的工作方式不同:与一个简单的Scala打包示例的混淆,scala,package,scala-2.8,Scala,Package,Scala 2.8,在Scala中打包类和导入包的问题上,我一直感到困惑。让我从一对简单的源文件开始: 文件:a/a.scala 文件:a/b/b.scala 使用 在A.scala中,使用scalac编译可以毫无怨言地使用上述任何一种导入 尝试在REPL中加载这些文件的工作方式不同: $ scala Welcome to Scala version 2.8.0.r0-b20100714201327 (Java HotSpot(TM) Server VM, Java 1.6.0_20). Type in expre
$ scala
Welcome to Scala version 2.8.0.r0-b20100714201327 (Java HotSpot(TM) Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :l a/b/B.scala
Loading a/b/B.scala...
<console>:1: error: illegal start of definition
package a.b
^
defined class B
scala> :l a/A.scala
Loading a/A.scala...
<console>:1: error: illegal start of definition
package a
^
<console>:5: error: not found: value b
import b._
^
defined class A
scala>
$scala
欢迎使用Scala版本2.8.0.r0-b20100714201327(Java热点(TM)服务器虚拟机,Java 1.6.020)。
键入要计算的表达式。
键入:有关详细信息的帮助。
scala>:l a/b/b.scala
正在加载a/b/b.scala。。。
:1:错误:定义的开始非法
a.b包
^
定义的B类
scala>:l a/a.scala
正在加载a/a.scala。。。
:1:错误:定义的开始非法
a包
^
:5:错误:未找到:值b
进口b_
^
定义的A类
斯卡拉>
因此,我有一些问题:
- 在上面的
中导入的正确方法是什么A.scala
- 编译器似乎能够在没有
的情况下确定导入是相对于我们所在的包还是绝对导入。这就是我看到的吗\u root.
- 我在REPL中的操作是否正确?为什么看到包语句看起来如此不高兴,为什么导入b.\ucode>会生成错误
PS我知道目录结构不必与包装匹配。自愿这样做有助于我暂时减少困惑。首先,您不能在REPL中定义包。原因是REPL语句实际上被包装到
对象中。这就是:load命令失败的原因。如果要使用包,则需要编译源文件并将其添加到类路径
当试图解析要导入的符号时,编译器会尝试在实际作用域中找到它,即在编写时
import a._
import b._
这将导入来自程序包a
的所有内容以及来自程序包a.b
的所有内容。如果您在包a
内,则b
已经在您的范围内,第二次导入就足够了。
编译器最初还导入scala.\u
,因此您也可以使用相对导入,如import xml.\u
来导入scala.xml.\u
此外,还有一个名为嵌套包的功能,可以让您编写B.scala
之类的文件
package a
package b
class B { /* .... */ }
这将导致在该文件中导入来自包a
的所有内容
如果编译器无法将导入解析为相对符号,它将在默认包中查找(\u root\u
)。要从控制台加载类
scala>:粘贴-原始io/hacking/yourpackage/YourClass.scala
如果您的类有一个main,则可以使用以下命令调用它:
scala>io.hacking.yourpackage/YourClass.main(Array())
上面的两个package语句并不等同于package a.b
?@dino大多数情况下是这样的——不同的是,所有的“a”都被导入。另请参阅及其包含的链接。到目前为止,REPL中不能定义包的语句不正确-您可以使用:paste raw
命令完成此操作-粘贴包定义的整个代码,然后按Ctrl+D
运行它。
import a._
import b._
package a
package b
class B { /* .... */ }