Skip to content

Commit 82bc07c

Browse files
benluojulienrf
authored andcommitted
add code tabs _zh-cn/overviews/scala3-book/methods-main-methods.md
1 parent f445e8d commit 82bc07c

File tree

1 file changed

+43
-14
lines changed

1 file changed

+43
-14
lines changed

_zh-cn/overviews/scala3-book/methods-main-methods.md

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,16 @@ permalink: "/zh-cn/scala3/book/:title.html"
1616

1717
Scala 3 提供了一种定义可以从命令行调用的程序的新方法:在方法中添加 `@main` 注释会将其变成可执行程序的入口点:
1818

19+
{% tabs method_1 %}
20+
{% tab 'Scala 3 Only' for=method_1 %}
21+
1922
```scala
2023
@main def hello() = println("Hello, world")
2124
```
2225

26+
{% endtab %}
27+
{% endtabs %}
28+
2329
只需将该行代码保存在一个名为 *Hello.scala* 的文件中——文件名不必与方法名匹配——并使用 `scalac` 编译它:
2430

2531
```bash
@@ -36,11 +42,20 @@ Hello, world
3642
`@main` 注释方法可以写在顶层(如图所示),也可以写在静态可访问的对象中。
3743
在任何一种情况下,程序的名称都是方法的名称,没有任何对象前缀。
3844

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+
3951
### 命令行参数
4052

4153
使用这种方法,您的`@main` 方法可以处理命令行参数,并且这些参数可以有不同的类型。
4254
例如,给定这个 `@main` 方法,它接受一个 `Int`、一个 `String` 和一个可变参数 `String*` 参数:
4355

56+
{% tabs method_2 %}
57+
{% tab 'Scala 3 Only' for=method_2 %}
58+
4459
```scala
4560
@main def happyBirthday(age: Int, name: String, others: String*) =
4661
val suffix = (age % 100) match
@@ -56,6 +71,9 @@ Hello, world
5671
sb.toString
5772
```
5873

74+
{% endtab %}
75+
{% endtabs %}
76+
5977
当你编译该代码时,它会创建一个名为 `happyBirthday` 的主程序,它的调用方式如下:
6078

6179
```
@@ -64,7 +82,7 @@ Happy 23rd Birthday, Lisa and Peter!
6482
```
6583

6684
如图所示,`@main` 方法可以有任意数量的参数。
67-
对于每个参数类型,必须有一个 *scala.util.FromString* 类型类的实例,它将参数 `String` 转换为所需的参数类型。
85+
对于每个参数类型,必须是 `scala.util.CommandLineParser.FromString` 类型类的一个 [given实例](./ca-given-using-clauses.html),它将参数 `String` 转换为所需的参数类型。
6886
同样如图所示,主方法的参数列表可以以重复参数结尾,例如 `String*`,它接受命令行中给出的所有剩余参数。
6987

7088
`@main` 方法实现的程序检查命令行上是否有足够的参数来填充所有参数,以及参数字符串是否可以转换为所需的类型。
@@ -88,6 +106,9 @@ Scala 编译器从 `@main` 方法 `f` 生成程序,如下所示:
88106

89107
例如,上面的 `happyBirthday` 方法会生成与以下类等效的附加代码:
90108

109+
{% tabs method_3 %}
110+
{% tab 'Scala 3 Only' for=method_3 %}
111+
91112
```scala
92113
final class happyBirthday {
93114
import scala.util.{CommandLineParser as CLP}
@@ -107,34 +128,42 @@ final class happyBirthday {
107128
> 此功能不适用于 Scala 中的用户程序。
108129
> 常规“静态”成员在 Scala 中使用对象生成。
109130
110-
## Scala 3 与 Scala 2 的比较
131+
{% endtab %}
132+
{% endtabs %}
133+
134+
## 与 Scala 2 的向后兼容性
111135

112136
`@main` 方法是在 Scala 3 中生成可以从命令行调用的程序的推荐方法。
113137
它们取代了 Scala 2 中以前的方法,即创建一个扩展 `App` 类的 `object`
114138

115-
```scala
116-
// scala 2
117-
object happyBirthday extends App {
118-
// needs by-hand parsing of the command line arguments ...
119-
}
120-
```
121-
122139
之前依赖于“神奇”的 `DelayedInit` trait 的 `App` 功能不再可用。
123140
`App` 目前仍以有限的形式存在,但它不支持命令行参数,将来会被弃用。
124141

125142
如果程序需要在 Scala 2 和 Scala 3 之间交叉构建,建议使用带有 `Array[String]` 参数的显式 `main` 方法:
126143

144+
{% tabs method_4 %}
145+
{% tab 'Scala 2 and 3' %}
146+
127147
```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+
}
130155
```
131156

157+
> 注意我们用 `:_*` 来传递不定数量的参数。为了保持向后兼容性,Scala 3 保持了这种用法。
158+
159+
{% endtab %}
160+
{% endtabs %}
161+
132162
如果将该代码放在名为 *happyBirthday.scala* 的文件中,则可以使用 `scalac` 编译它并使用 `scala` 运行它,如前所示:
133163

134164
```bash
135165
$ scalac happyBirthday.scala
136166

137-
$ scala happyBirthday
138-
Hello, world
167+
$ scala happyBirthday 23 Lisa Peter
168+
Happy 23rd Birthday, Lisa and Peter!
139169
```
140-

0 commit comments

Comments
 (0)