![Scala编程实战(原书第2版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/899/48593899/b_48593899.jpg)
1.4 scalac和scala命令
问题
虽然你通常会使用像sbt或Mill这样的工具来构建Scala应用程序,但偶尔你可能会想使用更基础的工具来编译和运行小型测试程序,就像你可能会使用javac和java来处理小型Java应用程序一样。
解决方案
用scalac编译小程序,然后用scala运行它们。例如,有以下名为Hello.scala的Scala源码文件:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/38_01.jpg?sign=1738954179-S6X8BuyQckaTVNJIXBH3l3Bqvxjovqw9-0-2d52b8c9ceb5b281bdf1cfea4a35d3c3)
使用scalac在命令行中编译:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/38_02.jpg?sign=1738954179-vKJ6HdcGsXsPYBhSUihiB9L3RHEC9gUJ-0-baf0dbd1da15765cc5701de66295e278)
然后用scala运行它,给scala命令传递一个用@main标记的方法名:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/38_03.jpg?sign=1738954179-YxhZqaNugHlZVtdWjPMdCIgS68FyR6sI-0-9f553931c0263414cb5d536574ff958f)
讨论
在Scala中,编译和运行类(包括像classpath这样的概念)与Java是一样的。例如,假设有一个名为Pizza.scala的文件中有一个Pizza类,并且它依赖一个Topping类型:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/38_04.jpg?sign=1738954179-jHDCiN4fLzz7935P67oFIEzfxMaIVfOJ-0-7a04998a08f0bd839fb437d612c7986c)
假设Topping的定义是这样的:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/38_05.jpg?sign=1738954179-9OE80ivof9spVLIly8z4sLK6JLMy2llx-0-b6f901dd52ed13d424d6a0a4fb304668)
它在名为Topping.scala的文件中,并且已经在一个名为classes的子目录中被编译成了Topping.class,可以这样编译Pizza.scala:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/38_06.jpg?sign=1738954179-bXW6dANbt833LjUENpbf8Qq6epqEplDD-0-77ae8deac146038c72eb668e75818c46)
注意,scalac命令有很多额外的选项可以使用。例如,如果你在前面的命令中加上-verbose选项,你会看到数百行额外用来显示scalac是如何工作的输出行。这些选项可能会随着时间的推移而改变,所以可以使用-help选项来查看额外的信息:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/39_01.jpg?sign=1738954179-Wd5Zb2KK4im9NZBChmH9v8BKS3EgJ2q7-0-7913e9b1dbb9a911be00bb74f61590c2)
main方法
在我们谈论编译main方法的时候,需要了解Scala 3可以用两种方式来声明main方法:
·在一个方法上使用@main注解。
·在一个object中声明一个签名正确的main方法。
如上所述,一个简单的无参@main方法可以这样声明:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/39_02.jpg?sign=1738954179-C4LOMaudMTyWsyssMi8zeaqflXhNeZgv-0-69b135665983d8864e5371db0fa9da8a)
也可以声明一个@main方法来接收命令行传入的参数,比如在这个例子中接收一个String和一个Int类型的参数:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/39_03.jpg?sign=1738954179-KPXSluhd2Njhk4UGRscEkOw6K1le72pH-0-a3075457d4475bd0e4656407bcaae150)
在使用scalac编译这段代码后,可以这样来运行:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/39_04.jpg?sign=1738954179-2lgGWwUzBPUnMIfvXxbcsLUFfyFEUmJx-0-cd358d8dee41c015fc382626012cf76a)
对于第二种方法,在object内部声明main方法就像在Java中声明main方法一样,而Scala中的main方法的签名必须是这样的:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/39_05.jpg?sign=1738954179-KCS6viEQMxFzEehxEWIMTP6rPEHd8IgC-0-7e4cf399e07f1e595b73dd2e34fe6edd)
这段Scala代码与下面的Java代码类似:
![](https://epubservercos.yuewen.com/87A2C8/28235253302644106/epubprivate/OEBPS/Images/39_06.jpg?sign=1738954179-fJWye7khUjPJzprXH9UEmdJEh12La13G-0-e0e1a2830e5660d2e99ad214ddb3d422)