Skip to content

add code tabs in num10. #2582

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 6 commits into from
Oct 7, 2022
Merged
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
81 changes: 52 additions & 29 deletions _overviews/scala3-book/taste-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,99 +14,120 @@ next-page: taste-functions
Scala classes, case classes, traits, enums, and objects can all contain methods.
The syntax of a simple method looks like this:

{% 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 %}

Here are a few examples:

{% 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 %}

You don’t have to declare a method’s return type, so you can write those methods like this, if you prefer:

{% 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 %}

This is how you call those methods:

{% tabs method_4 %}
{% tab 'Scala 2 and 3' for=method_4 %}
```scala
val x = sum(1, 2)
val y = concatenate("foo", "bar")
```
{% endtab %}
{% endtabs %}

Here’s an example of a multiline method:

{% 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 %}

Method parameters can also have default values.
In this example, the `timeout` parameter has a default value of `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 %}

Because a default `timeout` value is supplied in the method declaration, the method can be called in these two ways:

{% 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 also supports the use of _named parameters_ when calling a method, so you can also call that method like this, if you prefer:

{% tabs method_8 %}
{% tab 'Scala 2 and 3' for=method_8 %}
```scala
makeConnection(
url = "https://localhost",
timeout = 2500
)
```
{% endtab %}
{% endtabs %}

Named parameters are particularly useful when multiple method parameters have the same type.
At a glance, with this method you may wonder which parameters are set to `true` or `false`:

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

Without help from an IDE that code can be hard to read, but this code is much more obvious:
{% tabs method_9 %}
{% tab 'Scala 2 and 3' for=method_9 %}

```scala
engage(
speedIsSet = true,
directionIsSet = true,
picardSaidMakeItSo = true,
turnedOffParkingBrake = false
)
engage(true, true, true, false)
```



## Extension methods

_Extension methods_ let you add new methods to closed classes.
For instance, if you want to add two methods named `hello` and `aloha` to the `String` class, declare them as extension methods:

```scala
extension (s: String)
def hello: String = s"Hello, ${s.capitalize}!"
def aloha: String = s"Aloha, ${s.capitalize}!"

"world".hello // "Hello, World!"
"friend".aloha // "Aloha, Friend!"
```
{% endtab %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these three lines should be removed

```
{% endtab %}
% endtabs %}

{% endtabs %}

The `extension` keyword declares that you’re about to define one or more extension methods on the parameter that’s put in parentheses.
As shown with this example, the parameter `s` of type `String` can then be used in the body of your extension methods.
Expand All @@ -115,6 +136,9 @@ This next example shows how to add a `makeInt` method to the `String` class.
Here, `makeInt` takes a parameter named `radix`.
The code doesn’t account for possible string-to-integer conversion errors, but skipping that detail, the examples show how it works:

{% tabs extension_2 class=tabs-scala-version %}
{% tab 'Scala 3 Only' for=extension_2 %}

```scala
extension (s: String)
def makeInt(radix: Int): Int = Integer.parseInt(s, radix)
Expand All @@ -124,13 +148,12 @@ extension (s: String)
"100".makeInt(2) // Int = 4
```


{% endtab %}
{% endtabs %}

## See also

Scala Methods can be much more powerful: they can take type parameters and context parameters.
They are covered in detail in the [Domain Modeling][data-1] section.



[data-1]: {% link _overviews/scala3-book/domain-modeling-tools.md %}