|
| 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: 14 |
| 11 | +previous-page: taste-collections |
| 12 | +next-page: taste-toplevel-definitions |
| 13 | +--- |
| 14 | + |
| 15 | + |
| 16 | +При определенных обстоятельствах вы можете опустить некоторые параметры вызовов методов, которые считаются повторяющимися. |
| 17 | + |
| 18 | +Эти параметры называются _параметрами контекста_ (_Context Parameters_), |
| 19 | +поскольку они выводятся компилятором из контекста, окружающего вызов метода. |
| 20 | + |
| 21 | +Например, рассмотрим программу, которая сортирует список адресов по двум критериям: |
| 22 | +название города, а затем название улицы. |
| 23 | + |
| 24 | +{% tabs contextual_1 %} |
| 25 | +{% tab 'Scala 2 and 3' for=contextual_1 %} |
| 26 | + |
| 27 | +```scala |
| 28 | +val addresses: List[Address] = ... |
| 29 | + |
| 30 | +addresses.sortBy(address => (address.city, address.street)) |
| 31 | +``` |
| 32 | + |
| 33 | +{% endtab %} |
| 34 | +{% endtabs %} |
| 35 | + |
| 36 | +Метод `sortBy` принимает функцию, которая возвращает для каждого адреса значение, чтобы сравнить его с другими адресами. |
| 37 | +В этом случае мы передаем функцию, которая возвращает пару, содержащую название города и название улицы. |
| 38 | + |
| 39 | +Обратите внимание, что мы только указываем, _что_ сравнивать, но не _как_ выполнять сравнение. |
| 40 | +Откуда алгоритм сортировки знает, как сравнивать пары `String`? |
| 41 | + |
| 42 | +На самом деле метод `sortBy` принимает второй параметр — параметр контекста, который выводится компилятором. |
| 43 | +Его нет в приведенном выше примере, поскольку он предоставляется компилятором. |
| 44 | + |
| 45 | +Этот второй параметр реализует _способ_ сравнения. |
| 46 | +Его удобно опустить, потому что мы знаем, что `String`-и обычно сравниваются в лексикографическом порядке. |
| 47 | + |
| 48 | +Однако также возможно передать параметр явно: |
| 49 | + |
| 50 | +{% tabs contextual_2 class=tabs-scala-version %} |
| 51 | +{% tab 'Scala 2' for=contextual_2 %} |
| 52 | + |
| 53 | +```scala |
| 54 | +addresses.sortBy(address => (address.city, address.street))(Ordering.Tuple2(Ordering.String, Ordering.String)) |
| 55 | +``` |
| 56 | + |
| 57 | +{% endtab %} |
| 58 | +{% tab 'Scala 3' for=contextual_2 %} |
| 59 | + |
| 60 | +```scala |
| 61 | +addresses.sortBy(address => (address.city, address.street))(using Ordering.Tuple2(Ordering.String, Ordering.String)) |
| 62 | +``` |
| 63 | + |
| 64 | +в Scala 3 `using` в списке аргументов сигнализирует `sortBy` о явной передаче параметра контекста, избегая двусмысленности. |
| 65 | + |
| 66 | +{% endtab %} |
| 67 | +{% endtabs %} |
| 68 | + |
| 69 | +В этом случае экземпляр `Ordering.Tuple2(Ordering.String, Ordering.String)` — это именно тот экземпляр, |
| 70 | +который в противном случае выводится компилятором. |
| 71 | +Другими словами, оба примера создают одну и ту же программу. |
| 72 | + |
| 73 | +_Контекстные абстракции_ используются, чтобы избежать повторения кода. |
| 74 | +Они помогают разработчикам писать фрагменты кода, которые являются расширяемыми и в то же время лаконичными. |
| 75 | + |
| 76 | +Дополнительные сведения см. в [главе "Контекстные абстракции"][contextual] этой книги, а также в [справочной документации][reference]. |
| 77 | + |
| 78 | +[contextual]: {% link _overviews/scala3-book/ca-contextual-abstractions-intro.md %} |
| 79 | +[reference]: {{ site.scala3ref }}/overview.html |
0 commit comments