|
| 1 | +--- |
| 2 | +layout: multipage-overview |
| 3 | +title: Методы |
| 4 | +scala3: true |
| 5 | +partof: scala3-book |
| 6 | +overview-name: "Scala 3 — Book" |
| 7 | +type: chapter |
| 8 | +description: В этом разделе представлено введение в определение и использование методов в Scala 3. |
| 9 | +language: ru |
| 10 | +num: 10 |
| 11 | +previous-page: taste-modeling |
| 12 | +next-page: taste-functions |
| 13 | +--- |
| 14 | + |
| 15 | + |
| 16 | +## Методы в Scala |
| 17 | + |
| 18 | +Классы Scala, case-классы, трейты, перечисления и объекты могут содержать методы. |
| 19 | +Синтаксис простого метода выглядит так: |
| 20 | + |
| 21 | +{% tabs method_1 %} |
| 22 | +{% tab 'Scala 2 and 3' for=method_1 %} |
| 23 | +```scala |
| 24 | +def methodName(param1: Type1, param2: Type2): ReturnType = |
| 25 | + // тело метода |
| 26 | + // находится здесь |
| 27 | +``` |
| 28 | +{% endtab %} |
| 29 | +{% endtabs %} |
| 30 | + |
| 31 | +Вот несколько примеров: |
| 32 | + |
| 33 | +{% tabs method_2 %} |
| 34 | +{% tab 'Scala 2 and 3' for=method_2 %} |
| 35 | +```scala |
| 36 | +def sum(a: Int, b: Int): Int = a + b |
| 37 | +def concatenate(s1: String, s2: String): String = s1 + s2 |
| 38 | +``` |
| 39 | +{% endtab %} |
| 40 | +{% endtabs %} |
| 41 | + |
| 42 | +Вам не нужно объявлять возвращаемый тип метода, поэтому можно написать эти методы следующим образом, если хотите: |
| 43 | + |
| 44 | +{% tabs method_3 %} |
| 45 | +{% tab 'Scala 2 and 3' for=method_3 %} |
| 46 | +```scala |
| 47 | +def sum(a: Int, b: Int) = a + b |
| 48 | +def concatenate(s1: String, s2: String) = s1 + s2 |
| 49 | +``` |
| 50 | +{% endtab %} |
| 51 | +{% endtabs %} |
| 52 | + |
| 53 | +Вот как эти методы вызываются: |
| 54 | + |
| 55 | +{% tabs method_4 %} |
| 56 | +{% tab 'Scala 2 and 3' for=method_4 %} |
| 57 | +```scala |
| 58 | +val x = sum(1, 2) |
| 59 | +val y = concatenate("foo", "bar") |
| 60 | +``` |
| 61 | +{% endtab %} |
| 62 | +{% endtabs %} |
| 63 | + |
| 64 | +Вот пример многострочного метода: |
| 65 | + |
| 66 | +{% tabs method_5 class=tabs-scala-version %} |
| 67 | +{% tab 'Scala 2' for=method_5 %} |
| 68 | +```scala |
| 69 | +def getStackTraceAsString(t: Throwable): String = { |
| 70 | + val sw = new StringWriter |
| 71 | + t.printStackTrace(new PrintWriter(sw)) |
| 72 | + sw.toString |
| 73 | +} |
| 74 | +``` |
| 75 | +{% endtab %} |
| 76 | + |
| 77 | +{% tab 'Scala 3' for=method_5 %} |
| 78 | +```scala |
| 79 | +def getStackTraceAsString(t: Throwable): String = |
| 80 | + val sw = new StringWriter |
| 81 | + t.printStackTrace(new PrintWriter(sw)) |
| 82 | + sw.toString |
| 83 | +``` |
| 84 | +{% endtab %} |
| 85 | +{% endtabs %} |
| 86 | + |
| 87 | +Параметры метода также могут иметь значения по умолчанию. |
| 88 | +В этом примере параметр `timeout` имеет значение по умолчанию `5000`: |
| 89 | + |
| 90 | +{% tabs method_6 %} |
| 91 | +{% tab 'Scala 2 and 3' for=method_6 %} |
| 92 | +```scala |
| 93 | +def makeConnection(url: String, timeout: Int = 5000): Unit = |
| 94 | + println(s"url=$url, timeout=$timeout") |
| 95 | +``` |
| 96 | +{% endtab %} |
| 97 | +{% endtabs %} |
| 98 | + |
| 99 | +Поскольку в объявлении метода указано значение по умолчанию для `timeout`, метод можно вызывать двумя способами: |
| 100 | + |
| 101 | +{% tabs method_7 %} |
| 102 | +{% tab 'Scala 2 and 3' for=method_7 %} |
| 103 | +```scala |
| 104 | +makeConnection("https://localhost") // url=http://localhost, timeout=5000 |
| 105 | +makeConnection("https://localhost", 2500) // url=http://localhost, timeout=2500 |
| 106 | +``` |
| 107 | +{% endtab %} |
| 108 | +{% endtabs %} |
| 109 | + |
| 110 | +Scala также поддерживает использование _именованных параметров_ при вызове метода, |
| 111 | +поэтому вы можете вызвать этот метод, если хотите, вот так: |
| 112 | + |
| 113 | +{% tabs method_8 %} |
| 114 | +{% tab 'Scala 2 and 3' for=method_8 %} |
| 115 | +```scala |
| 116 | +makeConnection( |
| 117 | + url = "https://localhost", |
| 118 | + timeout = 2500 |
| 119 | +) |
| 120 | +``` |
| 121 | +{% endtab %} |
| 122 | +{% endtabs %} |
| 123 | + |
| 124 | +Именованные параметры особенно полезны, когда несколько параметров метода имеют один и тот же тип. |
| 125 | +Глядя на этот метод можно задаться вопросом, |
| 126 | +какие параметры установлены в `true` или `false`: |
| 127 | + |
| 128 | +{% tabs method_9 %} |
| 129 | +{% tab 'Scala 2 and 3' for=method_9 %} |
| 130 | + |
| 131 | +```scala |
| 132 | +engage(true, true, true, false) |
| 133 | +``` |
| 134 | + |
| 135 | +{% endtab %} |
| 136 | +{% endtabs %} |
| 137 | + |
| 138 | +Ключевое слово `extension` объявляет о намерении определить один или несколько методов расширения для параметра, |
| 139 | +заключенного в круглые скобки. |
| 140 | +Как показано в этом примере, параметр `s` типа `String` можно затем использовать в теле методов расширения. |
| 141 | + |
| 142 | +В следующем примере показано, как добавить метод `makeInt` в класс `String`. |
| 143 | +Здесь `makeInt` принимает параметр с именем `radix`. |
| 144 | +Код не учитывает возможные ошибки преобразования строки в целое число, |
| 145 | +но, опуская эту деталь, примеры показывают, как работают методы расширения: |
| 146 | + |
| 147 | +{% tabs extension %} |
| 148 | +{% tab 'Scala 3 Only' %} |
| 149 | + |
| 150 | +```scala |
| 151 | +extension (s: String) |
| 152 | + def makeInt(radix: Int): Int = Integer.parseInt(s, radix) |
| 153 | + |
| 154 | +"1".makeInt(2) // Int = 1 |
| 155 | +"10".makeInt(2) // Int = 2 |
| 156 | +"100".makeInt(2) // Int = 4 |
| 157 | +``` |
| 158 | + |
| 159 | +{% endtab %} |
| 160 | +{% endtabs %} |
| 161 | + |
| 162 | +## Смотрите также |
| 163 | + |
| 164 | +Методы Scala могут быть гораздо более мощными: они могут принимать параметры типа и параметры контекста. |
| 165 | +Методы подробно описаны в разделе ["Моделирование предметной области"][data-1]. |
| 166 | + |
| 167 | +[data-1]: {% link _overviews/scala3-book/domain-modeling-tools.md %} |
0 commit comments