@@ -16,10 +16,16 @@ permalink: "/zh-cn/scala3/book/:title.html"
16
16
17
17
Scala 3 提供了一种定义可以从命令行调用的程序的新方法:在方法中添加 ` @main ` 注释会将其变成可执行程序的入口点:
18
18
19
+ {% tabs method_1 %}
20
+ {% tab 'Scala 3 Only' for=method_1 %}
21
+
19
22
``` scala
20
23
@ main def hello () = println(" Hello, world" )
21
24
```
22
25
26
+ {% endtab %}
27
+ {% endtabs %}
28
+
23
29
只需将该行代码保存在一个名为 * Hello.scala* 的文件中——文件名不必与方法名匹配——并使用 ` scalac ` 编译它:
24
30
25
31
``` bash
@@ -36,11 +42,20 @@ Hello, world
36
42
` @main ` 注释方法可以写在顶层(如图所示),也可以写在静态可访问的对象中。
37
43
在任何一种情况下,程序的名称都是方法的名称,没有任何对象前缀。
38
44
45
+ 学习更多 ` @main ` 注解,可以阅读以下章节,或者看这个视频:
46
+
47
+ <div style =" text-align : center " >
48
+ <iframe width =" 560 " height =" 315 " src =" https://www.youtube.com/embed/uVMGPrH5_Uc " title =" YouTube video player " frameborder =" 0 " allow =" accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture " allowfullscreen ></iframe >
49
+ </div >
50
+
39
51
### 命令行参数
40
52
41
53
使用这种方法,您的` @main ` 方法可以处理命令行参数,并且这些参数可以有不同的类型。
42
54
例如,给定这个 ` @main ` 方法,它接受一个 ` Int ` 、一个 ` String ` 和一个可变参数 ` String* ` 参数:
43
55
56
+ {% tabs method_2 %}
57
+ {% tab 'Scala 3 Only' for=method_2 %}
58
+
44
59
``` scala
45
60
@ main def happyBirthday (age : Int , name : String , others : String * ) =
46
61
val suffix = (age % 100 ) match
@@ -56,6 +71,9 @@ Hello, world
56
71
sb.toString
57
72
```
58
73
74
+ {% endtab %}
75
+ {% endtabs %}
76
+
59
77
当你编译该代码时,它会创建一个名为 ` happyBirthday ` 的主程序,它的调用方式如下:
60
78
61
79
```
@@ -64,7 +82,7 @@ Happy 23rd Birthday, Lisa and Peter!
64
82
```
65
83
66
84
如图所示,` @main ` 方法可以有任意数量的参数。
67
- 对于每个参数类型,必须有一个 * scala.util.FromString* 类型类的实例 ,它将参数 ` String ` 转换为所需的参数类型。
85
+ 对于每个参数类型,必须是 ` scala.util.CommandLineParser. FromString ` 类型类的一个 [ given实例 ] ( ./ca-given-using-clauses.html ) ,它将参数 ` String ` 转换为所需的参数类型。
68
86
同样如图所示,主方法的参数列表可以以重复参数结尾,例如 ` String* ` ,它接受命令行中给出的所有剩余参数。
69
87
70
88
从 ` @main ` 方法实现的程序检查命令行上是否有足够的参数来填充所有参数,以及参数字符串是否可以转换为所需的类型。
@@ -88,6 +106,9 @@ Scala 编译器从 `@main` 方法 `f` 生成程序,如下所示:
88
106
89
107
例如,上面的 ` happyBirthday ` 方法会生成与以下类等效的附加代码:
90
108
109
+ {% tabs method_3 %}
110
+ {% tab 'Scala 3 Only' for=method_3 %}
111
+
91
112
``` scala
92
113
final class happyBirthday {
93
114
import scala .util .{CommandLineParser as CLP }
@@ -107,34 +128,42 @@ final class happyBirthday {
107
128
> 此功能不适用于 Scala 中的用户程序。
108
129
> 常规“静态”成员在 Scala 中使用对象生成。
109
130
110
- ## Scala 3 与 Scala 2 的比较
131
+ {% endtab %}
132
+ {% endtabs %}
133
+
134
+ ## 与 Scala 2 的向后兼容性
111
135
112
136
` @main ` 方法是在 Scala 3 中生成可以从命令行调用的程序的推荐方法。
113
137
它们取代了 Scala 2 中以前的方法,即创建一个扩展 ` App ` 类的 ` object ` :
114
138
115
- ``` scala
116
- // scala 2
117
- object happyBirthday extends App {
118
- // needs by-hand parsing of the command line arguments ...
119
- }
120
- ```
121
-
122
139
之前依赖于“神奇”的 ` DelayedInit ` trait 的 ` App ` 功能不再可用。
123
140
` App ` 目前仍以有限的形式存在,但它不支持命令行参数,将来会被弃用。
124
141
125
142
如果程序需要在 Scala 2 和 Scala 3 之间交叉构建,建议使用带有 ` Array[String] ` 参数的显式 ` main ` 方法:
126
143
144
+ {% tabs method_4 %}
145
+ {% tab 'Scala 2 and 3' %}
146
+
127
147
``` scala
128
- object happyBirthday :
129
- def main (args : Array [String ]) = println(" Hello, world" )
148
+ object happyBirthday {
149
+ private def happyBirthday (age : Int , name : String , others : String * ) = {
150
+ ... // same as before
151
+ }
152
+ def main (args : Array [String ]): Unit =
153
+ happyBirthday(args(0 ).toInt, args(1 ), args.drop(2 ).toIndexedSeq:_* )
154
+ }
130
155
```
131
156
157
+ > 注意我们用 ` :_* ` 来传递不定数量的参数。为了保持向后兼容性,Scala 3 保持了这种用法。
158
+
159
+ {% endtab %}
160
+ {% endtabs %}
161
+
132
162
如果将该代码放在名为 * happyBirthday.scala* 的文件中,则可以使用 ` scalac ` 编译它并使用 ` scala ` 运行它,如前所示:
133
163
134
164
``` bash
135
165
$ scalac happyBirthday.scala
136
166
137
- $ scala happyBirthday
138
- Hello, world
167
+ $ scala happyBirthday 23 Lisa Peter
168
+ Happy 23rd Birthday, Lisa and Peter !
139
169
```
140
-
0 commit comments