Skip to content

add code tabs in _zh-cn/overviews/scala3-book/taste-methods.md. #2681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions _zh-cn/overviews/scala3-book/taste-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,33 @@ Lambdas(也称为 _匿名函数_)是保持代码简洁但可读性的重要

这两个示例是等效的,并演示如何通过将 lambda 传递到 `map` 方法中,将列表中的每个数字乘以 `2`:


{% tabs function_1 %}
{% tab 'Scala 2 and 3' for=function_1 %}

```scala
val a = List(1, 2, 3).map(i => i * 2) // List(2,4,6)
val b = List(1, 2, 3).map(_ * 2) // List(2,4,6)
```

{% endtab %}
{% endtabs %}

这些示例也等效于以下代码,该代码使用 `double` 方法而不是lambda:

{% tabs function_2 %}
{% tab 'Scala 2 and 3' for=function_2 %}

```scala
def double(i: Int): Int = i * 2

val a = List(1, 2, 3).map(i => double(i)) // List(2,4,6)
val b = List(1, 2, 3).map(double) // List(2,4,6)
```

{% endtab %}
{% endtabs %}

> 如果您以前从未见过 `map` 方法,它会将给定的函数应用于列表中的每个元素,从而生成一个包含结果值的新列表。

将 lambda 传递给集合类上的高阶函数(如 `List`)是 Scala 体验的一部分,您每天都会这样做。
Expand All @@ -51,6 +64,9 @@ val b = List(1, 2, 3).map(double) // List(2,4,6)

例如,此示例演示如何对一个集合进行两次筛选,然后将其余集合中的每个元素乘某个数:

{% tabs function_3 %}
{% tab 'Scala 2 and 3' for=function_3 %}

```scala
// a sample list
val nums = (1 to 10).toList // List(1,2,3,4,5,6,7,8,9,10)
Expand All @@ -63,6 +79,9 @@ val x = nums.filter(_ > 3)
// result: x == List(40, 50, 60)
```

{% endtab %}
{% endtabs %}

除了在整个标准库中使用的高阶函数外,您还可以[创建自己的][higher-order] 高阶函数。

[higher-order]: {% link _zh-cn/overviews/scala3-book/fun-hofs.md %}
84 changes: 83 additions & 1 deletion _zh-cn/overviews/scala3-book/taste-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,75 +19,143 @@ permalink: "/zh-cn/scala3/book/:title.html"
Scala 类、样例类、traits、枚举和对象都可以包含方法。
简单方法的语法如下所示:

{% tabs method_1 %}
{% tab 'Scala 2 and 3' for=method_1 %}

```scala
def methodName(param1: Type1, param2: Type2): ReturnType =
// the method body
// goes here
```

{% endtab %}
{% endtabs %}

这有一些例子:

{% tabs method_2 %}
{% tab 'Scala 2 and 3' for=method_2 %}

```scala
def sum(a: Int, b: Int): Int = a + b
def concatenate(s1: String, s2: String): String = s1 + s2
```

{% endtab %}
{% endtabs %}

您不必声明方法的返回类型,因此如果您愿意,可以像这样编写这些方法:

{% tabs method_3 %}
{% tab 'Scala 2 and 3' for=method_3 %}

```scala
def sum(a: Int, b: Int) = a + b
def concatenate(s1: String, s2: String) = s1 + s2
```

{% endtab %}
{% endtabs %}

这是你如何调用这些方法:

{% tabs method_4 %}
{% tab 'Scala 2 and 3' for=method_4 %}

```scala
val x = sum(1, 2)
val y = concatenate("foo", "bar")
```

{% endtab %}
{% endtabs %}

这是一个多行的方法:

{% tabs method_5 class=tabs-scala-version %}
{% tab 'Scala 2' for=method_5 %}

```scala
def getStackTraceAsString(t: Throwable): String = {
val sw = new StringWriter
t.printStackTrace(new PrintWriter(sw))
sw.toString
}
```

{% endtab %}
{% tab 'Scala 3' for=method_5 %}

```scala
def getStackTraceAsString(t: Throwable): String =
val sw = new StringWriter
t.printStackTrace(new PrintWriter(sw))
sw.toString
```

{% endtab %}
{% endtabs %}

方法参数也可以具有默认值。
在此示例中,`timeout` 参数的默认值为 `5000`:

{% tabs method_6 %}
{% tab 'Scala 2 and 3' for=method_6 %}

```scala
def makeConnection(url: String, timeout: Int = 5000): Unit =
println(s"url=$url, timeout=$timeout")
```

{% endtab %}
{% endtabs %}

由于方法声明中提供了默认的 `超时` 值,因此可以通过以下两种方式调用该方法:

{% tabs method_7 %}
{% tab 'Scala 2 and 3' for=method_7 %}

```scala
makeConnection("https://localhost") // url=http://localhost, timeout=5000
makeConnection("https://localhost", 2500) // url=http://localhost, timeout=2500
```

{% endtab %}
{% endtabs %}

Scala 还支持在调用方法时使用 _命名参数_,因此如果您愿意,也可以像这样调用该方法:

{% tabs method_8 %}
{% tab 'Scala 2 and 3' for=method_8 %}

```scala
makeConnection(
url = "https://localhost",
timeout = 2500
)
```

{% endtab %}
{% endtabs %}

当多个方法参数具有相同的类型时,命名参数特别有用。
乍一看,使用此方法,您可能想知道哪些参数设置为 `true` 或 `false`:

{% tabs method_9 %}
{% tab 'Scala 2 and 3' for=method_9 %}

```scala
engage(true, true, true, false)
```

{% endtab %}
{% endtabs %}

如果没有IDE的帮助,那段代码可能很难阅读,但这个代码要明显得多:

{% tabs method_10 %}
{% tab 'Scala 2 and 3' for=method_10 %}

```scala
engage(
speedIsSet = true,
Expand All @@ -96,12 +164,17 @@ engage(
turnedOffParkingBrake = false
)
```
{% endtab %}
{% endtabs %}

## 扩展方法

_扩展方法_ 允许您向封闭类添加新方法。
例如,如果要将两个名为 `hello` 和 `aloha` 的方法添加到 `String` 类中,请将它们声明为扩展方法:

{% tabs extension0 %}
{% tab 'Scala 3 Only' %}

```scala
extension (s: String)
def hello: String = s"Hello, ${s.capitalize}!"
Expand All @@ -111,13 +184,19 @@ extension (s: String)
"friend".aloha // "Aloha, Friend!"
```

{% endtab %}
{% endtabs %}

`extension` 关键字声明了括号内的参数将定义一个或多个扩展方法。
如此示例所示,可以在扩展方法体中使用 `String` 类型的参数 `s`。

下一个示例演示如何将 `makeInt` 方法添加到 `String` 类。
在这里,`makeInt` 采用一个名为 `radix` 的参数。
该代码不考虑可能的字符串到整数转换错误,但跳过细节,示例显示了它的工作原理:

{% tabs extension %}
{% tab 'Scala 3 Only' %}

```scala
extension (s: String)
def makeInt(radix: Int): Int = Integer.parseInt(s, radix)
Expand All @@ -127,7 +206,10 @@ extension (s: String)
"100".makeInt(2) // Int = 4
```

## See also
{% endtab %}
{% endtabs %}

## 参见

Scala方法可以更强大:它们可以采用类型参数和上下文参数。
它们在[领域建模][data-1]一节中有详细介绍。
Expand Down