diff --git a/_ru/overviews/parallel-collections/concrete-parallel-collections.md b/_ru/overviews/parallel-collections/concrete-parallel-collections.md
index b6170ffe1d..1bda571a82 100644
--- a/_ru/overviews/parallel-collections/concrete-parallel-collections.md
+++ b/_ru/overviews/parallel-collections/concrete-parallel-collections.md
@@ -43,10 +43,10 @@ num: 2
[ParRange](https://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParRange.html) представляет собой упорядоченную последовательность элементов, отстоящих друг от друга на одинаковые промежутки. Параллельный диапазон создается подобно последовательному [Range](https://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html):
- scala> 1 to 3 par
+ scala> (1 to 3).par
res0: scala.collection.parallel.immutable.ParRange = ParRange(1, 2, 3)
- scala> 15 to 5 by -2 par
+ scala> (15 to 5 by -2).par
res1: scala.collection.parallel.immutable.ParRange = ParRange(15, 13, 11, 9, 7, 5)
Подобно тому, как последовательные диапазоны не имеют строителей, параллельные диапазоны не имеют [компоновщиков]({{ site.baseurl }}/ru/overviews/parallel-collections/architecture.html). При создании отображения (mapping) элементов параллельного диапазона получается параллельный вектор. Последовательные и параллельные диапазоны могут эффективно преобразовываться друг в друга вызовами методов `seq` и `par`.
@@ -72,7 +72,7 @@ num: 2
scala> val phs = scala.collection.parallel.immutable.ParHashSet(1 until 1000: _*)
phs: scala.collection.parallel.immutable.ParHashSet[Int] = ParSet(645, 892, 69, 809, 629, 365, 138, 760, 101, 479,...
- scala> phs map { x => x * x } sum
+ scala> phs.map(x => x * x).sum
res0: Int = 332833500
[Компоновщики]({{ site.baseurl }}/overviews/parallel-collections/architecture.html) параллельных хэш-деревьев действуют аналогично компоновщикам хэш-таблиц, а именно предварительно распределяют элементы по блокам, а после этого параллельно составляют результирующее хэш-дерево, назначая обработку различных блоков разным процессорам, каждый из которых независимо собирает свое поддерево.
@@ -88,19 +88,19 @@ num: 2
scala> while (numbers.nonEmpty) {
| numbers foreach { case (num, sqrt) =>
- | val nsqrt = 0.5 * (sqrt + num / sqrt)
- | numbers(num) = nsqrt
- | if (math.abs(nsqrt - sqrt) < 0.01) {
- | println(num, nsqrt)
- | numbers.remove(num)
- | }
- | }
- | }
- (1.0,1.0)
+ | val nsqrt = 0.5 * (sqrt + num / sqrt)
+ | numbers(num) = nsqrt
+ | if (math.abs(nsqrt - sqrt) < 0.01) {
+ | println(num, nsqrt)
+ | numbers.remove(num)
+ | }
+ | }
+ | }
+ (1.0,1.0)
(2.0,1.4142156862745097)
(7.0,2.64576704419029)
(4.0,2.0000000929222947)
- ...
+ ...
[Компоновщики]({{ site.baseurl }}/ru/overviews/parallel-collections/architecture.html) реализованы как `TrieMap`-- так как эта структура является многопоточной, при вызове метода трансформации создается только один компоновщик, разделяемый всеми процессорами.
@@ -110,53 +110,52 @@ num: 2
Характеристики производительности последовательных типов (sequence types):
-| | head | tail | apply | update| prepend | append | insert |
-| -------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
-| `ParArray` | C | L | C | C | L | L | L |
-| `ParVector` | eC | eC | eC | eC | eC | eC | - |
-| `ParRange` | C | C | C | - | - | - | - |
+| | head | tail | apply | update | prepend | append | insert |
+| ----------- | ---- | ---- | ----- | ------ | ------- | ------ | ------ |
+| `ParArray` | C | L | C | C | L | L | L |
+| `ParVector` | eC | eC | eC | eC | eC | eC | - |
+| `ParRange` | C | C | C | - | - | - | - |
Характеристики производительности множеств (set) и ассоциативных массивов (map):
-| | lookup | add | remove |
-| -------- | ---- | ---- | ---- |
-| **неизменяемые** | | | |
-| `ParHashSet`/`ParHashMap`| eC | eC | eC |
-| **изменяемые** | | | |
-| `ParHashSet`/`ParHashMap`| C | C | C |
-| `ParTrieMap` | eC | eC | eC |
-
+| | lookup | add | remove |
+| ------------------------- | ------ | --- | ------ |
+| **неизменяемые** | | | |
+| `ParHashSet`/`ParHashMap` | eC | eC | eC |
+| **изменяемые** | | | |
+| `ParHashSet`/`ParHashMap` | C | C | C |
+| `ParTrieMap` | eC | eC | eC |
### Расшифровка
Обозначения в двух представленных выше таблицах означают следующее:
-| | |
-| --- | ---- |
-| **C** | Операция (быстрая) выполняется за постоянное время. |
-| **eC** | Операция выполняется за фактически постоянное время, но только при соблюдении некоторых предположений, например о максимальной длине вектора или распределении хэш-кодов.|
+| | |
+| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| **C** | Операция (быстрая) выполняется за постоянное время. |
+| **eC** | Операция выполняется за фактически постоянное время, но только при соблюдении некоторых предположений, например о максимальной длине вектора или распределении хэш-кодов. |
| **aC** | Операция выполняется за амортизированное постоянное время. Некоторые вызовы операции могут выполняться медленнее, но при подсчете времени выполнения большого количества операций выходит, что в среднем на операцию требуется постоянное время. |
-| **Log** | Операция занимает время, пропорциональное логарифму размера коллекции. |
-| **L** | Операция линейна, то есть занимает время, пропорциональное размеру коллекции. |
-| **-** | Операция не поддерживается. |
+| **Log** | Операция занимает время, пропорциональное логарифму размера коллекции. |
+| **L** | Операция линейна, то есть занимает время, пропорциональное размеру коллекции. |
+| **-** | Операция не поддерживается. |
Первая таблица трактует последовательные типы-- изменяемые и неизменяемые-- в контексте выполнения следующих операций:
-| | |
-| --- | ---- |
-| **head** | Получение первого элемента последовательности. |
-| **tail** | Получение новой последовательности, состоящей из всех элементов исходной, кроме первого. |
-| **apply** | Индексирование. |
-| **update** | Функциональное обновление (с помощью `updated`) для неизменяемых последовательностей, обновление с побочными действиями (с помощью `update`) для изменяемых. |
-| **prepend**| Добавление элемента в начало последовательности. Для неизменяемых последовательностей создается новая последовательность, для изменяемых-- модифицируется существующая. |
-| **append** | Добавление элемента в конец последовательности. Для неизменяемых последовательностей создается новая последовательность, для изменяемых-- модифицируется существующая. |
-| **insert** | Вставка элемента в выбранную позицию последовательности. Поддерживается только изменяемыми последовательностями. |
+| | |
+| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **head** | Получение первого элемента последовательности. |
+| **tail** | Получение новой последовательности, состоящей из всех элементов исходной, кроме первого. |
+| **apply** | Индексирование. |
+| **update** | Функциональное обновление (с помощью `updated`) для неизменяемых последовательностей, обновление с побочными действиями (с помощью `update`) для изменяемых. |
+| **prepend** | Добавление элемента в начало последовательности. Для неизменяемых последовательностей создается новая последовательность, для изменяемых-- модифицируется существующая. |
+| **append** | Добавление элемента в конец последовательности. Для неизменяемых последовательностей создается новая последовательность, для изменяемых-- модифицируется существующая. |
+| **insert** | Вставка элемента в выбранную позицию последовательности. Поддерживается только изменяемыми последовательностями. |
Вторая таблица рассматривает изменяемые и неизменяемые множества и ассоциативные массивы в контексте следующих операций:
-| | |
-| --- | ---- |
+| | |
+| ---------- | ---------------------------------------------------------------------------------------------- |
| **lookup** | Проверка принадлежности элемента множеству, или получение значения, ассоциированного с ключом. |
-| **add** | Добавление нового элемента во множество или новой пары ключ/значение в ассоциативный массив. |
-| **remove** | Удаление элемента из множества или ключа из ассоциативного массива. |
-| **min** | Минимальный элемент множества или минимальный ключ ассоциативного массива. |
+| **add** | Добавление нового элемента во множество или новой пары ключ/значение в ассоциативный массив. |
+| **remove** | Удаление элемента из множества или ключа из ассоциативного массива. |
+| **min** | Минимальный элемент множества или минимальный ключ ассоциативного массива. |
diff --git a/_ru/scala3/book/fp-intro.md b/_ru/scala3/book/fp-intro.md
index a8a44521a2..5c9b3f5fad 100644
--- a/_ru/scala3/book/fp-intro.md
+++ b/_ru/scala3/book/fp-intro.md
@@ -12,16 +12,15 @@ previous-page: collections-summary
next-page: fp-what-is-fp
---
-
-Scala позволяет писать код в стиле объектно-ориентированного программирования (ООП),
-в стиле функционального программирования (ФП), а также в гибридном стиле, используя оба подхода в комбинации.
-По словам [Martin Odersky](https://twitter.com/alexelcu/status/996408359514525696),
+Scala позволяет писать код в стиле объектно-ориентированного программирования (ООП),
+в стиле функционального программирования (ФП), а также в гибридном стиле, используя оба подхода в комбинации.
+По словам Martin Odersky,
сущность Scala — это слияние функционального и объектно-ориентированного программирования в типизированной среде:
- Функции для логики
- Объекты для модульности
-В этой главе предполагается, что вы знакомы с ООП и менее знакомы с ФП,
+В этой главе предполагается, что вы знакомы с ООП и менее знакомы с ФП,
поэтому в ней представлено краткое введение в несколько основных концепций функционального программирования:
- Что такое функциональное программирование?
diff --git a/_ru/scala3/book/methods-main-methods.md b/_ru/scala3/book/methods-main-methods.md
index 46844f6485..cd6342216a 100644
--- a/_ru/scala3/book/methods-main-methods.md
+++ b/_ru/scala3/book/methods-main-methods.md
@@ -14,7 +14,7 @@ next-page: methods-summary
Написание однострочных программ только в Scala 3
-Scala 3 предлагает следующий способ определения программ, которые можно вызывать из командной строки:
+Scala 3 предлагает следующий способ определения программ, которые можно вызывать из командной строки:
добавление аннотации `@main` к методу превращает его в точку входа исполняемой программы:
{% tabs method_1 %}
@@ -27,7 +27,7 @@ Scala 3 предлагает следующий способ определен
{% endtab %}
{% endtabs %}
-Для запуска программы достаточно сохранить эту строку кода в файле с именем, например, _Hello.scala_
+Для запуска программы достаточно сохранить эту строку кода в файле с именем, например, _Hello.scala_
(имя файла необязательно должно совпадать с именем метода) и запустить с помощью `scala`:
```bash
@@ -35,8 +35,8 @@ $ scala Hello.scala
Hello, World
```
-Аннотированный метод `@main` может быть написан либо на верхнем уровне (как показано),
-либо внутри статически доступного объекта.
+Аннотированный метод `@main` может быть написан либо на верхнем уровне (как показано),
+либо внутри статически доступного объекта.
В любом случае имя программы - это имя метода без каких-либо префиксов объектов.
Узнайте больше об аннотации `@main`, прочитав следующие разделы или посмотрев это видео:
@@ -47,7 +47,7 @@ Hello, World
### Аргументы командной строки
-Метод `@main` может обрабатывать аргументы командной строки с различными типами.
+Метод `@main` может обрабатывать аргументы командной строки с различными типами.
Например, данный метод `@main`, который принимает параметры `Int`, `String` и дополнительные строковые параметры:
{% tabs method_2 %}
@@ -78,15 +78,15 @@ $ scala happyBirthday 23 Lisa Peter
Happy 23rd Birthday, Lisa and Peter!
```
-Как показано, метод `@main` может иметь произвольное количество параметров.
-Для каждого типа параметра должен существовать [given экземпляр][given]
-класса типа `scala.util.CommandLineParser.FromString`, который преобразует аргумент из `String` в требуемый тип параметра.
-Также, как показано, список параметров основного метода может заканчиваться повторяющимся параметром типа `String*`,
+Как показано, метод `@main` может иметь произвольное количество параметров.
+Для каждого типа параметра должен существовать [given экземпляр][given]
+класса типа `scala.util.CommandLineParser.FromString`, который преобразует аргумент из `String` в требуемый тип параметра.
+Также, как показано, список параметров основного метода может заканчиваться повторяющимся параметром типа `String*`,
который принимает все оставшиеся аргументы, указанные в командной строке.
-Программа, реализованная с помощью метода `@main`, проверяет,
-что в командной строке достаточно аргументов для заполнения всех параметров,
-и что строки аргументов могут быть преобразованы в требуемые типы.
+Программа, реализованная с помощью метода `@main`, проверяет,
+что в командной строке достаточно аргументов для заполнения всех параметров,
+и что строки аргументов могут быть преобразованы в требуемые типы.
Если проверка завершается неудачей, программа завершается с сообщением об ошибке:
```
@@ -97,20 +97,47 @@ $ scala happyBirthday sixty Fred
Illegal command line: java.lang.NumberFormatException: For input string: "sixty"
```
+## Пользовательские типы как параметры
+
+Как упоминалось выше, компилятор ищет заданный экземпляр класса типов `scala.util.CommandLineParser.FromString`
+для типа аргумента. Например, предположим, что у вас есть собственный тип `Color`,
+который вы хотите использовать в качестве параметра.
+Вы можете сделать это, как показано ниже:
+
+{% tabs method_3 %}
+{% tab 'Только в Scala 3' for=method_3 %}
+
+```scala
+enum Color:
+ case Red, Green, Blue
+
+given ComamndLineParser.FromString[Color] with
+ def fromString(value: String): Color = Color.valueOf(value)
+
+@main def run(color: Color): Unit =
+ println(s"The color is ${color.toString}")
+```
+
+{% endtab %}
+{% endtabs %}
+
+Это работает одинаково для ваших собственных пользовательских типов в вашей программе,
+а также для типов, которые можно использовать из другой библиотеки.
+
## Детали
Компилятор Scala генерирует программу из `@main` метода `f` следующим образом:
- он создает класс с именем `f` в пакете, где был найден метод `@main`.
-- класс имеет статический метод `main` с обычной сигнатурой Java `main` метода:
+- класс имеет статический метод `main` с обычной сигнатурой Java `main` метода:
принимает `Array[String]` в качестве аргумента и возвращает `Unit`.
-- сгенерированный `main` метод вызывает метод `f` с аргументами,
+- сгенерированный `main` метод вызывает метод `f` с аргументами,
преобразованными с помощью методов в объекте `scala.util.CommandLineParser.FromString`.
Например, приведенный выше метод `happyBirthday` генерирует дополнительный код, эквивалентный следующему классу:
-{% tabs method_3 %}
-{% tab 'Только в Scala 3' for=method_3 %}
+{% tabs method_4 %}
+{% tab 'Только в Scala 3' for=method_4 %}
```scala
final class happyBirthday {
@@ -127,9 +154,9 @@ final class happyBirthday {
}
```
-> Примечание: В этом сгенерированном коде модификатор `` выражает,
-> что `main` метод генерируется как статический метод класса `happyBirthday`.
-> Эта функция недоступна для пользовательских программ в Scala.
+> Примечание: В этом сгенерированном коде модификатор `` выражает,
+> что `main` метод генерируется как статический метод класса `happyBirthday`.
+> Эта функция недоступна для пользовательских программ в Scala.
> Вместо неё обычные “статические” члены генерируются в Scala с использованием `object`.
{% endtab %}
@@ -137,16 +164,16 @@ final class happyBirthday {
## Обратная совместимость со Scala 2
-`@main` методы — это рекомендуемый способ создания программ, вызываемых из командной строки в Scala 3.
+`@main` методы — это рекомендуемый способ создания программ, вызываемых из командной строки в Scala 3.
Они заменяют предыдущий подход, который заключался в создании `object`, расширяющего класс `App`:
-Прежняя функциональность `App`, основанная на "волшебном" `DelayedInit trait`, больше недоступна.
+Прежняя функциональность `App`, основанная на "волшебном" `DelayedInit trait`, больше недоступна.
`App` все еще существует в ограниченной форме, но не поддерживает аргументы командной строки и будет объявлен устаревшим в будущем.
-Если программам необходимо выполнять перекрестную сборку между Scala 2 и Scala 3,
+Если программам необходимо выполнять перекрестную сборку между Scala 2 и Scala 3,
вместо этого рекомендуется использовать `object` с явным методом `main` и одним аргументом `Array[String]`:
-{% tabs method_4 %}
+{% tabs method_5 %}
{% tab 'Scala 2 и 3' %}
```scala
@@ -159,13 +186,13 @@ object happyBirthday {
}
```
-> обратите внимание, что здесь мы используем `:_*` для передачи переменного числа аргументов,
+> обратите внимание, что здесь мы используем `:_*` для передачи переменного числа аргументов,
> который остается в Scala 3 для обратной совместимости.
{% endtab %}
{% endtabs %}
-Если вы поместите этот код в файл с именем _happyBirthday.scala_, то сможете скомпилировать его с `scalac`
+Если вы поместите этот код в файл с именем _happyBirthday.scala_, то сможете скомпилировать его с `scalac`
и запустить с помощью `scala`, как показывалось ранее:
```bash
diff --git a/_ru/scala3/book/types-others.md b/_ru/scala3/book/types-others.md
index 5f01514837..131bdd403b 100644
--- a/_ru/scala3/book/types-others.md
+++ b/_ru/scala3/book/types-others.md
@@ -24,5 +24,7 @@ versionSpecific: true
- Вид полиморфизма
Дополнительные сведения об этих типах см. в [Справочной документации Scala 3][reference].
+Для singleton типов см. раздел [literal types](https://scala-lang.org/files/archive/spec/3.4/03-types.html#literal-types)
+спецификации Scala 3, а для уточненных типов — раздел [refined types](https://scala-lang.org/files/archive/spec/3.4/03-types.html).
[reference]: {{ site.scala3ref }}/overview.html
diff --git a/_ru/scala3/guides/scaladoc/settings.md b/_ru/scala3/guides/scaladoc/settings.md
index c36dedb135..e8d68554c9 100644
--- a/_ru/scala3/guides/scaladoc/settings.md
+++ b/_ru/scala3/guides/scaladoc/settings.md
@@ -40,6 +40,8 @@ Compile / doc / scalacOptions ++= Seq("-project", "my-project"),
##### -project-logo
Логотип проекта, который появляется в верхнем левом углу.
+Для темной темы можно выделить отдельный логотип с суффиксом `_dark`.
+Например, если есть логотип `mylogo.png`, то для темной темы предполагается `mylogo_dark.png`.
Чтобы обеспечить совместимость с псевдонимами Scala2 с `-doc-logo`
##### -project-footer
diff --git a/_ru/tour/named-arguments.md b/_ru/tour/named-arguments.md
index 5b2376cf4b..da9202a051 100644
--- a/_ru/tour/named-arguments.md
+++ b/_ru/tour/named-arguments.md
@@ -17,27 +17,40 @@ prerequisite-knowledge: function-syntax
```scala mdoc
def printName(first: String, last: String): Unit =
- println(first + " " + last)
+ println(s"$first $last")
-printName("John", "Smith") // выводит "John Smith"
-printName(first = "John", last = "Smith") // выводит "John Smith"
-printName(last = "Smith", first = "John") // выводит "John Smith"
+printName("John", "Public") // выводит "John Public"
+printName(first = "John", last = "Public") // выводит "John Public"
+printName(last = "Public", first = "John") // выводит "John Public"
+printName("Elton", last = "John") // выводит "Elton John"
```
{% endtab %}
{% endtabs %}
-Обратите внимание, что при указании имени параметра, порядок аргумента может быть изменен.
-Однако если какие-то аргументы именованные, а другие нет,
-то аргументы без имени должны стоять на первом месте и располагаться в том порядке, в котором описаны параметры метода.
+Это полезно, когда два параметра имеют один и тот же тип и аргументы могут быть случайно перепутаны.
+
+Обратите внимание, что именованные аргументы могут быть указаны в любом порядке.
+Однако, если аргументы расположены не в порядке параметров метода (читается слева направо),
+остальные аргументы должны быть названы.
+
+В следующем примере именованные аргументы позволяют опустить параметр `middle`.
+В случае ошибки, если первый аргумент не на своем месте, необходимо будет указать второй аргумент.
{% tabs named-arguments-when-error %}
{% tab 'Scala 2 и 3' for=named-arguments-when-error %}
```scala mdoc:fail
-printName(last = "Smith", "john") // ошибка: позиция после именованного аргумента
+def printFullName(first: String, middle: String = "Q.", last: String): Unit =
+ println(s"$first $middle $last")
+
+printFullName(first = "John", last = "Public") // выводит "John Q. Public"
+printFullName("John", last = "Public") // выводит "John Q. Public"
+printFullName("John", middle = "Quincy", "Public") // выводит "John Quincy Public"
+printFullName(last = "Public", first = "John") // выводит "John Q. Public"
+printFullName(last = "Public", "John") // ошибка: позиция после именованного аргумента
```
{% endtab %}
@@ -45,4 +58,4 @@ printName(last = "Smith", "john") // ошибка: позиция после и
{% endtabs %}
Именованные аргументы работают при вызове Java методов, но только в том случае,
-если используемая Java библиотека была скомпилирована с `-parameters`.
+если используемая Java библиотека была скомпилирована с флагом `-parameters`.