From 10777d08f01e3f101eb3aaf457d1b4ebc7918f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 09:13:46 +0300 Subject: [PATCH 01/15] Add taste-repl.md in russian --- _overviews/scala3-book/taste-repl.md | 2 +- _ru/scala3/book/taste-hello-world.md | 2 +- _ru/scala3/book/taste-repl.md | 93 ++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 _ru/scala3/book/taste-repl.md diff --git a/_overviews/scala3-book/taste-repl.md b/_overviews/scala3-book/taste-repl.md index 868b38222c..784eaca131 100644 --- a/_overviews/scala3-book/taste-repl.md +++ b/_overviews/scala3-book/taste-repl.md @@ -2,7 +2,7 @@ title: The REPL type: section description: This section provides an introduction to the Scala REPL. -languages: [zh-cn] +languages: [ru, zh-cn] num: 6 previous-page: taste-hello-world next-page: taste-vars-data-types diff --git a/_ru/scala3/book/taste-hello-world.md b/_ru/scala3/book/taste-hello-world.md index 1a029de9ef..e96ab3511d 100644 --- a/_ru/scala3/book/taste-hello-world.md +++ b/_ru/scala3/book/taste-hello-world.md @@ -9,7 +9,7 @@ description: В этом примере демонстрируется прим language: ru num: 5 previous-page: taste-intro -next-page: +next-page: taste-repl --- > **Подсказка**: в следующих примерах попробуйте выбрать предпочтительную для вас версию Scala. diff --git a/_ru/scala3/book/taste-repl.md b/_ru/scala3/book/taste-repl.md new file mode 100644 index 0000000000..40f4c98808 --- /dev/null +++ b/_ru/scala3/book/taste-repl.md @@ -0,0 +1,93 @@ +--- +layout: multipage-overview +title: REPL +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: В этом разделе представлено введение в Scala REPL. +language: ru +num: 6 +previous-page: taste-hello-world +next-page: taste-vars-data-types +--- + +Scala REPL (“Read-Evaluate-Print-Loop”) - это интерпретатор командной строки, +который используется в качестве “игровой площадки” для тестирования Scala кода. +Для того чтобы запустить сеанс REPL, надо выполнить команду `scala` или `scala3` в зависимости от операционной системы, +затем будет выведено приглашение “Welcome”, подобное этому: + +{% tabs command-line class=tabs-scala-version %} + +{% tab 'Scala 2' for=command-line %} +```bash +$ scala +Welcome to Scala {{site.scala-version}} (OpenJDK 64-Bit Server VM, Java 1.8.0_342). +Type in expressions for evaluation. Or try :help. + +scala> _ +``` +{% endtab %} + +{% tab 'Scala 3' for=command-line %} +```bash +$ scala +Welcome to Scala {{site.scala-3-version}} (1.8.0_322, Java OpenJDK 64-Bit Server VM). +Type in expressions for evaluation. Or try :help. + +scala> _ +``` +{% endtab %} + +{% endtabs %} + +REPL — это интерпретатор командной строки, поэтому он ждет, пока вы что-нибудь наберете. +Теперь можно вводить выражения Scala, чтобы увидеть, как они работают: + +{% tabs expression-one %} +{% tab 'Scala 2 and 3' for=expression-one %} +```` +scala> 1 + 1 +val res0: Int = 2 + +scala> 2 + 2 +val res1: Int = 4 +```` +{% endtab %} +{% endtabs %} + +Как показано в выводе, если не присваивать переменную результату выражения, +REPL автоматически создает для вас переменные с именами `res0`, `res1` и т.д. +Эти имена переменных можно использовать в последующих выражениях: + +{% tabs expression-two %} +{% tab 'Scala 2 and 3' for=expression-two %} +```` +scala> val x = res0 * 10 +val x: Int = 20 +```` +{% endtab %} +{% endtabs %} + +Обратите внимание, что в REPL output также показываются результаты выражений. + +В REPL можно проводить всевозможные эксперименты. +В этом примере показано, как создать, а затем вызвать метод `sum`: + +{% tabs expression-three %} +{% tab 'Scala 2 and 3' for=expression-three %} +```` +scala> def sum(a: Int, b: Int): Int = a + b +def sum(a: Int, b: Int): Int + +scala> sum(2, 2) +val res2: Int = 4 +```` +{% endtab %} +{% endtabs %} + +Также можно использовать игровую среду на основе браузера [scastie.scala-lang.org](https://scastie.scala-lang.org). + +Если вы предпочитаете писать код в текстовом редакторе, а не в консоли, то можно использовать [worksheet]. + +[worksheet]: {% link _overviews/scala3-book/tools-worksheets.md %} From 6ffa19d8c60b1059585f99eb4fa27e75009c8462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 09:47:18 +0300 Subject: [PATCH 02/15] Add taste-vars-data-types.md in russian --- .../scala3-book/taste-vars-data-types.md | 2 +- _ru/scala3/book/taste-vars-data-types.md | 276 ++++++++++++++++++ 2 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-vars-data-types.md diff --git a/_overviews/scala3-book/taste-vars-data-types.md b/_overviews/scala3-book/taste-vars-data-types.md index 750264bcd2..194e2d7f40 100644 --- a/_overviews/scala3-book/taste-vars-data-types.md +++ b/_overviews/scala3-book/taste-vars-data-types.md @@ -2,7 +2,7 @@ title: Variables and Data Types type: section description: This section demonstrates val and var variables, and some common Scala data types. -languages: [zh-cn] +languages: [ru, zh-cn] num: 7 previous-page: taste-repl next-page: taste-control-structures diff --git a/_ru/scala3/book/taste-vars-data-types.md b/_ru/scala3/book/taste-vars-data-types.md new file mode 100644 index 0000000000..09451765a4 --- /dev/null +++ b/_ru/scala3/book/taste-vars-data-types.md @@ -0,0 +1,276 @@ +--- +layout: multipage-overview +title: Переменные и типы данных +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: В этом разделе демонстрируются переменные val и var, а также некоторые распространенные типы данных Scala. +language: ru +num: 7 +previous-page: taste-repl +next-page: taste-control-structures +--- + + +В этом разделе представлен обзор переменных и типов данных Scala. + +## Два вида переменных + +Когда вы создаете новую переменную в Scala, то объявляете, является ли переменная неизменяемой или изменяемой: + + + + + + + + + + + + + + + + + + +
Тип переменнойОписание
valСоздает неизменяемую переменную — как final в Java. Вы всегда должны создавать переменную с val, если нет причины, по которой вам нужна изменяемая переменная.
varСоздает изменяемую переменную и должна использоваться только в том случае, если содержимое переменной будет меняться с течением времени.
+ +Эти примеры показывают, как создавать `val` и `var` переменные: + +{% tabs var-express-1 %} +{% tab 'Scala 2 and 3' %} + +```scala +// неизменяемая +val a = 0 + +// изменяемая +var b = 1 +``` +{% endtab %} +{% endtabs %} + +В программе `val` переназначить нельзя. +Появится ошибка компилятора, если попытаться её изменить: + +{% tabs var-express-2 %} +{% tab 'Scala 2 and 3' %} + +```scala +val msg = "Hello, world" +msg = "Aloha" // ошибка "reassignment to val"; этот код не скомпилируется +``` +{% endtab %} +{% endtabs %} + +И наоборот, `var` можно переназначить: + +{% tabs var-express-3 %} +{% tab 'Scala 2 and 3' %} + +```scala +var msg = "Hello, world" +msg = "Aloha" // этот код скомпилируется, потому что var может быть переназначена +``` +{% endtab %} +{% endtabs %} + +## Объявление типов переменных + +Когда вы создаете переменную, то можете явно объявить ее тип или позволить компилятору его вывести: + +{% tabs var-express-4 %} +{% tab 'Scala 2 and 3' %} + +```scala +val x: Int = 1 // явно +val x = 1 // неявно; компилятор выводит тип +``` +{% endtab %} +{% endtabs %} + +Вторая форма известна как _вывод типа_, и это отличный способ сделать кратким код такого типа. +Компилятор Scala обычно может определить тип данных за вас, как показано в выводе этих примеров REPL: + +{% tabs var-express-5 %} +{% tab 'Scala 2 and 3' %} + +```scala +scala> val x = 1 +val x: Int = 1 + +scala> val s = "a string" +val s: String = a string + +scala> val nums = List(1, 2, 3) +val nums: List[Int] = List(1, 2, 3) +``` +{% endtab %} +{% endtabs %} + +Вы всегда можете явно объявить тип переменной, если хотите, +но в простых присваиваниях, подобных нижеследующим, в этом нет необходимости: + +{% tabs var-express-6 %} +{% tab 'Scala 2 and 3' %} + +```scala +val x: Int = 1 +val s: String = "a string" +val p: Person = Person("Richard") +``` +{% endtab %} +{% endtabs %} + +Обратите внимание, что при таком подходе код кажется более многословным, чем необходимо. + +## Встроенные типы данных + +Scala поставляется со стандартными числовыми типами данных, которые вы ожидаете, +и все они являются полноценными экземплярами классов. +В Scala все является объектом. + +Эти примеры показывают, как объявлять переменные числовых типов: + +{% tabs var-express-7 %} +{% tab 'Scala 2 and 3' %} + +```scala +val b: Byte = 1 +val i: Int = 1 +val l: Long = 1 +val s: Short = 1 +val d: Double = 2.0 +val f: Float = 3.0 +``` +{% endtab %} +{% endtabs %} + +Поскольку `Int` и `Double` являются числовыми типами по умолчанию, то обычно они создаются без явного объявления типа: + +{% tabs var-express-8 %} +{% tab 'Scala 2 and 3' %} + +```scala +val i = 123 // по умолчанию Int +val j = 1.0 // по умолчанию Double +``` +{% endtab %} +{% endtabs %} + +В своем коде вы также можете добавлять символы `L`, `D` и `F` (и их эквиваленты в нижнем регистре) к числам, +чтобы указать, что они являются `Long`, `Double` или `Float` значениями: + +{% tabs var-express-9 %} +{% tab 'Scala 2 and 3' %} + +```scala +val x = 1_000L // val x: Long = 1000 +val y = 2.2D // val y: Double = 2.2 +val z = 3.3F // val z: Float = 3.3 +``` +{% endtab %} +{% endtabs %} + +Когда вам нужны действительно большие числа, используйте типы `BigInt` и `BigDecimal`: + +{% tabs var-express-10 %} +{% tab 'Scala 2 and 3' %} + +```scala +var a = BigInt(1_234_567_890_987_654_321L) +var b = BigDecimal(123_456.789) +``` +{% endtab %} +{% endtabs %} + +Где `Double` и `Float` - это приблизительные десятичные числа, а `BigDecimal` используется для точной арифметики. + +В Scala также есть типы данных `String` и `Char`: + +{% tabs var-express-11 %} +{% tab 'Scala 2 and 3' %} + +```scala +val name = "Bill" // String +val c = 'a' // Char +``` +{% endtab %} +{% endtabs %} + +### Строки + +Строки Scala похожи на строки Java, но у них есть две замечательные дополнительные функции: + +- Они поддерживают интерполяцию строк +- Легко создавать многострочные строки + +#### Строковая интерполяция + +Интерполяция строк обеспечивает очень удобный способ использования переменных внутри строк. +Например, учитывая эти три переменные: + +{% tabs var-express-12 %} +{% tab 'Scala 2 and 3' %} + +```scala +val firstName = "John" +val mi = 'C' +val lastName = "Doe" +``` +{% endtab %} +{% endtabs %} + +Вы можете объединить эти переменные в строку следующим образом: + +{% tabs var-express-13 %} +{% tab 'Scala 2 and 3' %} + +```scala +println(s"Name: $firstName $mi $lastName") // "Name: John C Doe" +``` +{% endtab %} +{% endtabs %} + +Просто поставьте перед строкой букву `s`, а затем поставьте символ `$` перед именами переменных внутри строки. + +Чтобы вставить произвольные выражения в строку, заключите их в фигурные скобки: + +{% tabs var-express-14 %} +{% tab 'Scala 2 and 3' %} + +``` scala +println(s"2 + 2 = ${2 + 2}") // prints "2 + 2 = 4" + +val x = -1 +println(s"x.abs = ${x.abs}") // prints "x.abs = 1" +``` +{% endtab %} +{% endtabs %} + +Символ `s`, помещенный перед строкой, является лишь одним из возможных интерполяторов. +Если использовать `f` вместо `s`, можно использовать синтаксис форматирования в стиле `printf` в строке. +Кроме того, интерполятор строк - это всего лишь специальный метод, и его можно определить самостоятельно. +Например, некоторые библиотеки баз данных определяют очень мощный интерполятор `sql`. + +#### Многострочные строки + +Многострочные строки создаются путем включения строки в три двойные кавычки: + +{% tabs var-express-15 %} +{% tab 'Scala 2 and 3' %} + +```scala +val quote = """The essence of Scala: + Fusion of functional and object-oriented + programming in a typed setting.""" +``` +{% endtab %} +{% endtabs %} + +> Дополнительные сведения о строковых интерполяторах и многострочных строках см. в главе [“Первое знакомство с типами”][first-look]. + +[first-look]: {% link _overviews/scala3-book/first-look-at-types.md %} From 5db750cfe316fcec2a558bcda465ee7759f0f6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 10:36:50 +0300 Subject: [PATCH 03/15] Add taste-control-structures.md in russian --- .../scala3-book/taste-control-structures.md | 2 +- _ru/scala3/book/taste-control-structures.md | 555 ++++++++++++++++++ 2 files changed, 556 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-control-structures.md diff --git a/_overviews/scala3-book/taste-control-structures.md b/_overviews/scala3-book/taste-control-structures.md index 5a61bacb58..a8cf7f8f49 100644 --- a/_overviews/scala3-book/taste-control-structures.md +++ b/_overviews/scala3-book/taste-control-structures.md @@ -2,7 +2,7 @@ title: Control Structures type: section description: This section demonstrates Scala 3 control structures. -languages: [zh-cn] +languages: [ru, zh-cn] num: 8 previous-page: taste-vars-data-types next-page: taste-modeling diff --git a/_ru/scala3/book/taste-control-structures.md b/_ru/scala3/book/taste-control-structures.md new file mode 100644 index 0000000000..a25efe0db9 --- /dev/null +++ b/_ru/scala3/book/taste-control-structures.md @@ -0,0 +1,555 @@ +--- +layout: multipage-overview +title: Структуры управления +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: Этот раздел демонстрирует структуры управления в Scala 3. +language: ru +num: 8 +previous-page: taste-vars-data-types +next-page: taste-modeling +--- + + +В Scala есть все структуры управления, которые вы найдете в других языках программирования, +а также мощные `for` и `match` выражения: + +- `if`/`else` +- `for` циклы и выражения +- `match` выражения +- `while` циклы +- `try`/`catch` + +Эти структуры демонстрируются в следующих примерах. + +## `if`/`else` + +В Scala структура управления `if`/`else` похожа на аналогичные структуры в других языках. + +{% tabs if-else class=tabs-scala-version %} +{% tab 'Scala 2' for=if-else %} + +```scala +if (x < 0) { + println("negative") +} else if (x == 0) { + println("zero") +} else { + println("positive") +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=if-else %} + +```scala +if x < 0 then + println("negative") +else if x == 0 then + println("zero") +else + println("positive") +``` + +{% endtab %} +{% endtabs %} + +Обратите внимание, что это действительно _выражение_, а не _утверждение_. +Это означает, что оно возвращает значение, поэтому вы можете присвоить результат переменной: + +{% tabs if-else-expression class=tabs-scala-version %} +{% tab 'Scala 2' for=if-else-expression %} + +```scala +val x = if (a < b) { a } else { b } +``` + +{% endtab %} + +{% tab 'Scala 3' for=if-else-expression %} + +```scala +val x = if a < b then a else b +``` + +{% endtab %} +{% endtabs %} + +Как вы увидите в этой книге, _все_ управляющие структуры Scala могут использоваться как выражения. + +> Выражение возвращает результат, а утверждение — нет. +> Утверждения обычно используются для их побочных эффектов, таких как использование `println` для печати на консоли. + +## `for` циклы и выражения + +Ключевое слово `for` используется для создания цикла `for`. +В этом примере показано, как напечатать каждый элемент в `List`: + +{% tabs for-loop class=tabs-scala-version %} +{% tab 'Scala 2' for=for-loop %} + +```scala +val ints = List(1, 2, 3, 4, 5) + +for (i <- ints) println(i) +``` + +> Код `i <- ints` называется _генератором_, а код, следующий за закрывающими скобками генератора, является _телом_ цикла. + +{% endtab %} + +{% tab 'Scala 3' for=for-loop %} + +```scala +val ints = List(1, 2, 3, 4, 5) + +for i <- ints do println(i) +``` + +> Код `i <- ints` называется _генератором_, а код, следующий за ключевым словом `do`, является _телом_ цикла. + +{% endtab %} +{% endtabs %} + +### Guards + +Вы также можете использовать одно или несколько `if` выражений внутри цикла `for`. +Их называют _стражники_ (_guards_). +В этом примере выводятся все числа `ints`, большие `2`: + +{% tabs for-guards class=tabs-scala-version %} +{% tab 'Scala 2' for=for-guards %} + +```scala +for (i <- ints if i > 2) + println(i) +``` + +{% endtab %} + +{% tab 'Scala 3' for=for-guards %} + +```scala +for + i <- ints + if i > 2 +do + println(i) +``` + +{% endtab %} +{% endtabs %} + +Вы можете использовать несколько генераторов и стражников. +Этот цикл перебирает числа от `1` до `3`, и для каждого числа также перебирает символы от `a` до `c`. +Однако у него также есть два стражника, поэтому оператор печати вызывается только тогда, +когда `i` имеет значение `2` и `j` является символом `b`: + +{% tabs for-guards-multi class=tabs-scala-version %} +{% tab 'Scala 2' for=for-guards-multi %} + +```scala +for { + i <- 1 to 3 + j <- 'a' to 'c' + if i == 2 + if j == 'b' +} { + println(s"i = $i, j = $j") // печатает: "i = 2, j = b" +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=for-guards-multi %} + +```scala +for + i <- 1 to 3 + j <- 'a' to 'c' + if i == 2 + if j == 'b' +do + println(s"i = $i, j = $j") // печатает: "i = 2, j = b" +``` + +{% endtab %} +{% endtabs %} + +### Выражения `for` + +Ключевое слово `for` содержит в себе еще большую силу: +когда вы используете ключевое слово `yield` вместо `do`, то создаете _выражения_ `for`, +которые используются для вычислений и получения результатов. + +Несколько примеров демонстрируют это. +Используя тот же список `ints`, что и в предыдущем примере, этот код создает новый список, +в котором значение каждого элемента в новом списке в два раза превышает значение элементов в исходном: + +{% tabs for-expression_1 class=tabs-scala-version %} +{% tab 'Scala 2' for=for-expression_1 %} + +```` +scala> val doubles = for (i <- ints) yield i * 2 +val doubles: List[Int] = List(2, 4, 6, 8, 10) +```` + +{% endtab %} + +{% tab 'Scala 3' for=for-expression_1 %} + +```` +scala> val doubles = for i <- ints yield i * 2 +val doubles: List[Int] = List(2, 4, 6, 8, 10) +```` + +{% endtab %} +{% endtabs %} + +Синтаксис структуры управления Scala является гибким, +и это `for` выражение может быть записано несколькими другими способами, в зависимости от ваших предпочтений: + +{% tabs for-expressioni_2 class=tabs-scala-version %} +{% tab 'Scala 2' for=for-expressioni_2 %} + +```scala +val doubles = for (i <- ints) yield i * 2 +val doubles = for (i <- ints) yield (i * 2) +val doubles = for { i <- ints } yield (i * 2) +``` + +{% endtab %} + +{% tab 'Scala 3' for=for-expressioni_2 %} + +```scala +val doubles = for i <- ints yield i * 2 // стиль показан выше +val doubles = for (i <- ints) yield i * 2 +val doubles = for (i <- ints) yield (i * 2) +val doubles = for { i <- ints } yield (i * 2) +``` + +{% endtab %} +{% endtabs %} + +В этом примере показано, как сделать первый символ в каждой строке списка заглавными: + +{% tabs for-expressioni_3 class=tabs-scala-version %} +{% tab 'Scala 2' for=for-expressioni_3 %} + +```scala +val names = List("chris", "ed", "maurice") +val capNames = for (name <- names) yield name.capitalize +``` + +{% endtab %} + +{% tab 'Scala 3' for=for-expressioni_3 %} + +```scala +val names = List("chris", "ed", "maurice") +val capNames = for name <- names yield name.capitalize +``` + +{% endtab %} +{% endtabs %} + +Наконец, нижеследующее выражение `for` перебирает список строк +и возвращает длину каждой строки, но только если эта длина больше `4`: + +{% tabs for-expressioni_4 class=tabs-scala-version %} +{% tab 'Scala 2' for=for-expressioni_4 %} + +```scala +val fruits = List("apple", "banana", "lime", "orange") + +val fruitLengths = + for (f <- fruits if f.length > 4) yield f.length + +// fruitLengths: List[Int] = List(5, 6, 6) +``` + +{% endtab %} + +{% tab 'Scala 3' for=for-expressioni_4 %} + +```scala +val fruits = List("apple", "banana", "lime", "orange") + +val fruitLengths = for + f <- fruits + if f.length > 4 +yield + // здесь можно использовать + // несколько строк кода + f.length + +// fruitLengths: List[Int] = List(5, 6, 6) +``` + +{% endtab %} +{% endtabs %} + +`for` циклы и выражения более подробно рассматриваются в разделах этой книги ["Структуры управления"][control] +и в [справочной документации]({{ site.scala3ref }}/other-new-features/control-syntax.html). + +## `match` выражения + +В Scala есть выражение `match`, которое в своем самом простом использовании похоже на `switch` оператор Java: + +{% tabs match class=tabs-scala-version %} +{% tab 'Scala 2' for=match %} + +```scala +val i = 1 + +// позже в этом коде ... +i match { + case 1 => println("one") + case 2 => println("two") + case _ => println("other") +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=match %} + +```scala +val i = 1 + +// позже в этом коде ... +i match + case 1 => println("one") + case 2 => println("two") + case _ => println("other") +``` + +{% endtab %} +{% endtabs %} + +Однако `match` на самом деле это выражение, означающее, +что оно возвращает результат на основе совпадения с шаблоном, который вы можете привязать к переменной: + +{% tabs match-expression_1 class=tabs-scala-version %} +{% tab 'Scala 2' for=match-expression_1 %} + +```scala +val result = i match { + case 1 => "one" + case 2 => "two" + case _ => "other" +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=match-expression_1 %} + +```scala +val result = i match + case 1 => "one" + case 2 => "two" + case _ => "other" +``` + +{% endtab %} +{% endtabs %} + +`match` не ограничивается работой только с целочисленными значениями, его можно использовать с любым типом данных: + +{% tabs match-expression_2 class=tabs-scala-version %} +{% tab 'Scala 2' for=match-expression_2 %} + +```scala +val p = Person("Fred") + +// позже в этом коде ... +p match { + case Person(name) if name == "Fred" => + println(s"$name says, Yubba dubba doo") + + case Person(name) if name == "Bam Bam" => + println(s"$name says, Bam bam!") + + case _ => println("Watch the Flintstones!") +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=match-expression_2 %} + +```scala +val p = Person("Fred") + +// позже в этом коде ... +p match + case Person(name) if name == "Fred" => + println(s"$name says, Yubba dubba doo") + + case Person(name) if name == "Bam Bam" => + println(s"$name says, Bam bam!") + + case _ => println("Watch the Flintstones!") +``` + +{% endtab %} +{% endtabs %} + +На самом деле `match` выражение можно использовать для проверки переменной на множестве различных типов шаблонов. +В этом примере показано (а) как использовать `match` выражение в качестве тела метода и (б) как сопоставить все показанные различные типы: + +{% tabs match-expression_3 class=tabs-scala-version %} +{% tab 'Scala 2' for=match-expression_3 %} + +```scala +// getClassAsString - метод, принимающий один параметр любого типа. +def getClassAsString(x: Any): String = x match { + case s: String => s"'$s' is a String" + case i: Int => "Int" + case d: Double => "Double" + case l: List[_] => "List" + case _ => "Unknown" +} + +// примеры +getClassAsString(1) // Int +getClassAsString("hello") // 'hello' is a String +getClassAsString(List(1, 2, 3)) // List +``` + +Поскольку метод `getClassAsString` принимает значение параметра типа `Any`, его можно разложить по любому шаблону. + +{% endtab %} +{% tab 'Scala 3' for=match-expression_3 %} + +```scala +// getClassAsString - метод, принимающий один параметр любого типа. +def getClassAsString(x: Matchable): String = x match + case s: String => s"'$s' is a String" + case i: Int => "Int" + case d: Double => "Double" + case l: List[?] => "List" + case _ => "Unknown" + +// примеры +getClassAsString(1) // Int +getClassAsString("hello") // 'hello' is a String +getClassAsString(List(1, 2, 3)) // List +``` + +Метод `getClassAsString` принимает в качестве параметра значение типа [Matchable]({{ site.scala3ref }}/other-new-features/matchable.html), +которое может быть любым типом, поддерживающим сопоставление с образцом +(некоторые типы не поддерживают сопоставление с образцом, поскольку это может нарушить инкапсуляцию). + +{% endtab %} +{% endtabs %} + +Сопоставление с образцом в Scala гораздо _шире_. +Шаблоны могут быть вложены друг в друга, результаты шаблонов могут быть связаны, +а сопоставление шаблонов может даже определяться пользователем. +Дополнительные сведения см. в примерах сопоставления с образцом в главе ["Структуры управления"][control]. + +## `try`/`catch`/`finally` + +Структура управления Scala `try`/`catch`/`finally` позволяет перехватывать исключения. +Она похожа на аналогичную структуру в Java, но её синтаксис соответствует `match` выражениям: + +{% tabs try class=tabs-scala-version %} +{% tab 'Scala 2' for=try %} + +```scala +try { + writeTextToFile(text) +} catch { + case ioe: IOException => println("Got an IOException.") + case nfe: NumberFormatException => println("Got a NumberFormatException.") +} finally { + println("Clean up your resources here.") +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=try %} + +```scala +try + writeTextToFile(text) +catch + case ioe: IOException => println("Got an IOException.") + case nfe: NumberFormatException => println("Got a NumberFormatException.") +finally + println("Clean up your resources here.") +``` + +{% endtab %} +{% endtabs %} + +## Циклы `while` + +В Scala также есть конструкция цикла `while`. +Его однострочный синтаксис выглядит так: + +{% tabs while_1 class=tabs-scala-version %} +{% tab 'Scala 2' for=while_1 %} + +```scala +while (x >= 0) { x = f(x) } +``` + +{% endtab %} + +{% tab 'Scala 3' for=while_1 %} + +```scala +while x >= 0 do x = f(x) +``` +Scala 3 по-прежнему поддерживает синтаксис Scala 2 для обратной совместимости. + +{% endtab %} +{% endtabs %} + +Синтаксис `while` многострочного цикла выглядит следующим образом: + +{% tabs while_2 class=tabs-scala-version %} +{% tab 'Scala 2' for=while_2 %} + +```scala +var x = 1 + +while (x < 3) { + println(x) + x += 1 +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=while_2 %} + +```scala +var x = 1 + +while + x < 3 +do + println(x) + x += 1 +``` + +{% endtab %} +{% endtabs %} + +## Пользовательские структуры управления + +Благодаря таким функциям, как параметры по имени, инфиксная нотация, плавные интерфейсы, необязательные круглые скобки, +методы расширения и функции высшего порядка, вы также можете создавать свой собственный код, +который работает так же, как управляющая структура. +Вы узнаете об этом больше в разделе ["Структуры управления"][control]. + +[control]: {% link _overviews/scala3-book/control-structures.md %} From 82df29a4cd7fedf42e00330a94e6f31c22199666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 11:36:41 +0300 Subject: [PATCH 04/15] Add taste-modeling.md in russian --- _overviews/scala3-book/taste-modeling.md | 2 +- _ru/scala3/book/taste-modeling.md | 421 +++++++++++++++++++++++ 2 files changed, 422 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-modeling.md diff --git a/_overviews/scala3-book/taste-modeling.md b/_overviews/scala3-book/taste-modeling.md index f28ceb550e..2fe2f8e490 100644 --- a/_overviews/scala3-book/taste-modeling.md +++ b/_overviews/scala3-book/taste-modeling.md @@ -2,7 +2,7 @@ title: Domain Modeling type: section description: This section provides an introduction to data modeling in Scala 3. -languages: [zh-cn] +languages: [ru, zh-cn] num: 9 previous-page: taste-control-structures next-page: taste-methods diff --git a/_ru/scala3/book/taste-modeling.md b/_ru/scala3/book/taste-modeling.md new file mode 100644 index 0000000000..1dbe0c9a51 --- /dev/null +++ b/_ru/scala3/book/taste-modeling.md @@ -0,0 +1,421 @@ +--- +layout: multipage-overview +title: Моделирование данных +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: В этом разделе представлено введение в моделирование данных в Scala 3. +language: ru +num: 9 +previous-page: taste-control-structures +next-page: taste-methods +--- + + +Scala поддерживает как функциональное программирование (ФП), так и объектно-ориентированное программирование (ООП), +а также слияние этих двух парадигм. В этом разделе представлен краткий обзор моделирования данных в ООП и ФП. + +## Моделирование данных в ООП + +При написании кода в стиле ООП двумя вашими основными инструментами для инкапсуляции данных будут _трейты_ и _классы_. + +### Трейты + +Трейты Scala можно использовать как простые интерфейсы, +но они также могут содержать абстрактные и конкретные методы и поля, а также параметры, как и классы. +Они предоставляют вам отличный способ организовать поведение в небольшие модульные блоки. +Позже, когда вы захотите создать конкретные реализации атрибутов и поведения, +классы и объекты могут расширять трейты, смешивая столько трейтов, +сколько необходимо для достижения желаемого поведения. + +В качестве примера того, как использовать трейты в качестве интерфейсов, +вот три трейта, которые определяют хорошо организованное и модульное поведение для животных, таких как собаки и кошки: + +{% tabs traits class=tabs-scala-version %} +{% tab 'Scala 2' for=traits %} + +```scala +trait Speaker { + def speak(): String // тело метода отсутствует, поэтому метод абстрактный +} + +trait TailWagger { + def startTail(): Unit = println("tail is wagging") + def stopTail(): Unit = println("tail is stopped") +} + +trait Runner { + def startRunning(): Unit = println("I’m running") + def stopRunning(): Unit = println("Stopped running") +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=traits %} + +```scala +trait Speaker: + def speak(): String // тело метода отсутствует, поэтому метод абстрактный + +trait TailWagger: + def startTail(): Unit = println("tail is wagging") + def stopTail(): Unit = println("tail is stopped") + +trait Runner: + def startRunning(): Unit = println("I’m running") + def stopRunning(): Unit = println("Stopped running") +``` + +{% endtab %} +{% endtabs %} + +Учитывая эти трейты, вот класс `Dog`, который их все расширяет, +обеспечивая при этом поведение для абстрактного метода `speak`: + +{% tabs traits-class class=tabs-scala-version %} +{% tab 'Scala 2' for=traits-class %} + +```scala +class Dog(name: String) extends Speaker with TailWagger with Runner { + def speak(): String = "Woof!" +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=traits-class %} + +```scala +class Dog(name: String) extends Speaker, TailWagger, Runner: + def speak(): String = "Woof!" +``` + +{% endtab %} +{% endtabs %} + +Обратите внимание, как класс расширяет трейты с помощью ключевого слова `extends`. + +Точно так же вот класс `Cat`, реализующий те же трейты, +а также переопределяющий два конкретных метода, которые он наследует: + +{% tabs traits-override class=tabs-scala-version %} +{% tab 'Scala 2' for=traits-override %} + +```scala +class Cat(name: String) extends Speaker with TailWagger with Runner { + def speak(): String = "Meow" + override def startRunning(): Unit = println("Yeah ... I don’t run") + override def stopRunning(): Unit = println("No need to stop") +} +``` + +{% endtab %} + +{% tab 'Scala 3' for=traits-override %} + +```scala +class Cat(name: String) extends Speaker, TailWagger, Runner: + def speak(): String = "Meow" + override def startRunning(): Unit = println("Yeah ... I don’t run") + override def stopRunning(): Unit = println("No need to stop") +``` + +{% endtab %} +{% endtabs %} + +Примеры ниже показывают, как используются эти классы: + +{% tabs traits-use class=tabs-scala-version %} +{% tab 'Scala 2' for=traits-use %} + +```scala +val d = new Dog("Rover") +println(d.speak()) // печатает "Woof!" + +val c = new Cat("Morris") +println(c.speak()) // "Meow" +c.startRunning() // "Yeah ... I don’t run" +c.stopRunning() // "No need to stop" +``` + +{% endtab %} + +{% tab 'Scala 3' for=traits-use %} + +```scala +val d = Dog("Rover") +println(d.speak()) // печатает "Woof!" + +val c = Cat("Morris") +println(c.speak()) // "Meow" +c.startRunning() // "Yeah ... I don’t run" +c.stopRunning() // "No need to stop" +``` + +{% endtab %} +{% endtabs %} + +Если этот код имеет смысл — отлично, вам удобно использовать трейты в качестве интерфейсов. +Если нет, не волнуйтесь, они более подробно описаны в главе ["Моделирование предметной области"][data-1]. + + +### Классы + +Классы Scala используются в программировании в стиле ООП. +Вот пример класса, который моделирует "человека". +В ООП поля обычно изменяемы, поэтому оба, `firstName` и `lastName` объявлены как `var` параметры: + +{% tabs class_1 class=tabs-scala-version %} +{% tab 'Scala 2' for=class_1 %} + +```scala +class Person(var firstName: String, var lastName: String) { + def printFullName() = println(s"$firstName $lastName") +} + +val p = new Person("John", "Stephens") +println(p.firstName) // "John" +p.lastName = "Legend" +p.printFullName() // "John Legend" +``` + +{% endtab %} + +{% tab 'Scala 3' for=class_1 %} + +```scala +class Person(var firstName: String, var lastName: String): + def printFullName() = println(s"$firstName $lastName") + +val p = Person("John", "Stephens") +println(p.firstName) // "John" +p.lastName = "Legend" +p.printFullName() // "John Legend" +``` + +{% endtab %} +{% endtabs %} + +Обратите внимание, что объявление класса создает конструктор: + +{% tabs class_2 class=tabs-scala-version %} +{% tab 'Scala 2' for=class_2 %} + +```scala +// код использует конструктор из объявления класса +val p = new Person("John", "Stephens") +``` + +{% endtab %} + +{% tab 'Scala 3' for=class_2 %} + +```scala +// код использует конструктор из объявления класса +val p = Person("John", "Stephens") +``` + +{% endtab %} +{% endtabs %} + +Конструкторы и другие темы, связанные с классами, рассматриваются в главе ["Моделирование предметной области"][data-1]. + +## Моделирование данных в ФП + +При написании кода в стиле ФП вы будете использовать следующие понятия: + +- Алгебраические типы данных для определения данных. +- Трейты для функциональности данных. + +### Перечисления и суммированные типы + +Суммированные типы (_sum types_) — это один из способов моделирования алгебраических типов данных (ADT) в Scala. + +Они используются, когда данные могут быть представлены с различными вариантами. + +Например, у пиццы есть три основных атрибута: + +- Размер корки +- Тип корки +- Начинки +- +Они кратко смоделированы с помощью перечислений, +которые представляют собой суммированные типы, содержащие только одноэлементные значения: + +{% tabs enum_1 class=tabs-scala-version %} +{% tab 'Scala 2' for=enum_1 %} + +В Scala 2 `sealed` классы и `case object` объединяются для определения перечисления: + +```scala +sealed abstract class CrustSize +object CrustSize { + case object Small extends CrustSize + case object Medium extends CrustSize + case object Large extends CrustSize +} + +sealed abstract class CrustType +object CrustType { + case object Thin extends CrustType + case object Thick extends CrustType + case object Regular extends CrustType +} + +sealed abstract class Topping +object Topping { + case object Cheese extends Topping + case object Pepperoni extends Topping + case object BlackOlives extends Topping + case object GreenOlives extends Topping + case object Onions extends Topping +} +``` + +{% endtab %} +{% tab 'Scala 3' for=enum_1 %} + +Scala 3 предлагает конструкцию `enum` для определения перечислений: + +```scala +enum CrustSize: + case Small, Medium, Large + +enum CrustType: + case Thin, Thick, Regular + +enum Topping: + case Cheese, Pepperoni, BlackOlives, GreenOlives, Onions +``` + +{% endtab %} +{% endtabs %} + +Когда у вас есть перечисление, вы можете импортировать его элементы как обычные значения: + +{% tabs enum_2 class=tabs-scala-version %} +{% tab 'Scala 2' for=enum_2 %} + +```scala +import CrustSize._ +val currentCrustSize = Small + +// перечисления в сопоставлении с шаблоном +currentCrustSize match { + case Small => println("Small crust size") + case Medium => println("Medium crust size") + case Large => println("Large crust size") +} + +// перечисления в операторе `if` +if (currentCrustSize == Small) println("Small crust size") +``` + +{% endtab %} +{% tab 'Scala 3' for=enum_2 %} + +```scala +import CrustSize.* +val currentCrustSize = Small + +// перечисления в сопоставлении с шаблоном +currentCrustSize match + case Small => println("Small crust size") + case Medium => println("Medium crust size") + case Large => println("Large crust size") + +// перечисления в операторе `if` +if currentCrustSize == Small then println("Small crust size") +``` + +{% endtab %} +{% endtabs %} + +Вот еще один пример того, как создать суммированные типы с помощью Scala, +это не будет называться перечислением, потому что у случая `Succ` есть параметры: + +{% tabs enum_3 class=tabs-scala-version %} +{% tab 'Scala 2' for=enum_3 %} + +```scala +sealed abstract class Nat +object Nat { + case object Zero extends Nat + case class Succ(pred: Nat) extends Nat +} +``` + +Суммированные типы подробно рассматриваются в разделе ["Моделирование предметной области"]({% link _overviews/scala3-book/domain-modeling-tools.md %}) этой книги. + +{% endtab %} +{% tab 'Scala 3' for=enum_3 %} + +```scala +enum Nat: + case Zero + case Succ(pred: Nat) +``` + +Перечисления подробно рассматриваются в разделе ["Моделирование предметной области"]({% link _overviews/scala3-book/domain-modeling-tools.md %}) этой книги +и в [справочной документации]({{ site.scala3ref }}/enums/enums.html). + +{% endtab %} +{% endtabs %} + +### Продуктовые типы + +Тип продукта — это алгебраический тип данных (ADT), который имеет только одну форму, +например, одноэлементный объект, представленный в Scala `case object`; +или неизменяемая структура с доступными полями, представленная `case class`. + +`case class` обладает всеми функциями класса, а также содержит встроенные дополнительные функции, +которые делают его полезным для функционального программирования. +Когда компилятор видит ключевое слово `case` перед `class`, то применяет следующие эффекты и преимущества: + +- Параметры конструктора `case class` по умолчанию являются общедоступными полями `val`, поэтому поля неизменяемы, + а методы доступа генерируются для каждого параметра. +- Генерируется метод `unapply`, который позволяет использовать `case class` в выражениях match различными способами. +- В классе создается метод `copy`. Он позволяет создавать копии объекта без изменения исходного. +- Создаются методы `equals` и `hashCode` для реализации структурного равенства. +- Генерируется метод по умолчанию `toString`, полезный для отладки. + +Вы _можете_ вручную добавить все эти методы в класс самостоятельно, +но, поскольку эти функции так часто используются в функциональном программировании, +использование case класса гораздо удобнее. + +Этот код демонстрирует несколько функций `case class`: + +{% tabs case-class %} +{% tab 'Scala 2 and 3' for=case-class %} + +```scala +// определение case class +case class Person( + name: String, + vocation: String +) + +// создание экземпляра case class +val p = Person("Reginald Kenneth Dwight", "Singer") + +// полезный метод toString +p // : Person = Person(Reginald Kenneth Dwight,Singer) + +// можно получить доступ к неизменяемым полям +p.name // "Reginald Kenneth Dwight" +p.name = "Joe" // error: can’t reassign a val field + +// при необходимости внести изменения используйте метод `copy` +// для “update as you copy” +val p2 = p.copy(name = "Elton John") +p2 // : Person = Person(Elton John,Singer) +``` + +{% endtab %} +{% endtabs %} + +Дополнительные сведения о `case` классах см. в разделах ["Моделирование предметной области"][data-1]. + +[data-1]: {% link _overviews/scala3-book/domain-modeling-tools.md %} From 29c7cf477e19c71d868ae90047cf174902dcc2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 11:53:45 +0300 Subject: [PATCH 05/15] Add taste-methods.md in russian --- _overviews/scala3-book/taste-methods.md | 2 +- _ru/scala3/book/taste-methods.md | 167 ++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-methods.md diff --git a/_overviews/scala3-book/taste-methods.md b/_overviews/scala3-book/taste-methods.md index eaea32f7ef..6c54818805 100644 --- a/_overviews/scala3-book/taste-methods.md +++ b/_overviews/scala3-book/taste-methods.md @@ -2,7 +2,7 @@ title: Methods type: section description: This section provides an introduction to defining and using methods in Scala 3. -languages: [zh-cn] +languages: [ru, zh-cn] num: 10 previous-page: taste-modeling next-page: taste-functions diff --git a/_ru/scala3/book/taste-methods.md b/_ru/scala3/book/taste-methods.md new file mode 100644 index 0000000000..f624ac71c5 --- /dev/null +++ b/_ru/scala3/book/taste-methods.md @@ -0,0 +1,167 @@ +--- +layout: multipage-overview +title: Методы +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: В этом разделе представлено введение в определение и использование методов в Scala 3. +language: ru +num: 10 +previous-page: taste-modeling +next-page: taste-functions +--- + + +## Методы в Scala + +Классы Scala, case-классы, трейты, перечисления и объекты могут содержать методы. +Синтаксис простого метода выглядит так: + +{% tabs method_1 %} +{% tab 'Scala 2 and 3' for=method_1 %} +```scala +def methodName(param1: Type1, param2: Type2): ReturnType = + // тело метода + // находится здесь +``` +{% 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 %} + +Поскольку в объявлении метода указано значение по умолчанию для `timeout`, метод можно вызывать двумя способами: + +{% 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 %} + +Ключевое слово `extension` объявляет о намерении определить один или несколько методов расширения для параметра, +заключенного в круглые скобки. +Как показано в этом примере, параметр `s` типа `String` можно затем использовать в теле методов расширения. + +В следующем примере показано, как добавить метод `makeInt` в класс `String`. +Здесь `makeInt` принимает параметр с именем `radix`. +Код не учитывает возможные ошибки преобразования строки в целое число, +но, опуская эту деталь, примеры показывают, как работают методы расширения: + +{% tabs extension %} +{% tab 'Scala 3 Only' %} + +```scala +extension (s: String) + def makeInt(radix: Int): Int = Integer.parseInt(s, radix) + +"1".makeInt(2) // Int = 1 +"10".makeInt(2) // Int = 2 +"100".makeInt(2) // Int = 4 +``` + +{% endtab %} +{% endtabs %} + +## Смотрите также + +Методы Scala могут быть гораздо более мощными: они могут принимать параметры типа и параметры контекста. +Методы подробно описаны в разделе ["Моделирование предметной области"][data-1]. + +[data-1]: {% link _overviews/scala3-book/domain-modeling-tools.md %} From 30e88999745d332e37f72c0a78f0903a0a01e4bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 12:16:09 +0300 Subject: [PATCH 06/15] Add taste-functions.md in russian --- _overviews/scala3-book/taste-functions.md | 2 +- _ru/scala3/book/taste-functions.md | 90 +++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-functions.md diff --git a/_overviews/scala3-book/taste-functions.md b/_overviews/scala3-book/taste-functions.md index 42479e10a4..e73024bca0 100644 --- a/_overviews/scala3-book/taste-functions.md +++ b/_overviews/scala3-book/taste-functions.md @@ -2,7 +2,7 @@ title: First-Class Functions type: section description: This page provides an introduction to functions in Scala 3. -languages: [zh-cn] +languages: [ru, zh-cn] num: 11 previous-page: taste-methods next-page: taste-objects diff --git a/_ru/scala3/book/taste-functions.md b/_ru/scala3/book/taste-functions.md new file mode 100644 index 0000000000..6e8c44b50d --- /dev/null +++ b/_ru/scala3/book/taste-functions.md @@ -0,0 +1,90 @@ +--- +layout: multipage-overview +title: Функции первого класса +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: На этой странице представлено введение в функции в Scala 3. +language: ru +num: 11 +previous-page: taste-methods +next-page: taste-objects +--- + +Scala обладает большинством возможностей, которые вы ожидаете от функционального языка программирования, в том числе: + +- Lambdas (анонимные функции) +- Функции высшего порядка (HOF) +- Неизменяемые коллекции в стандартной библиотеке + +Лямбда-выражения, также известные как _анонимные функции_, играют важную роль в том, чтобы ваш код был кратким, но удобочитаемым. + +Метод `map` класса `List` является типичным примером функции высшего порядка — +функции, которая принимает функцию в качестве параметра. + +Эти два примера эквивалентны и показывают, как умножить каждое число в списке на `2`, передав лямбда в метод `map`: + + +{% 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`: + + +{% 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`, он применяет заданную функцию к каждому элементу в списке, +> создавая новый список, содержащий результирующие значения. + +Передача лямбда-выражений функциям высшего порядка в классах коллекций (таких, как `List`) — +это часть работы со Scala, которую вы будете делать каждый день. + + +## Неизменяемые коллекции + +Когда вы работаете с неизменяемыми коллекциями, такими как `List`, `Vector`, +а также с неизменяемыми классами `Map` и `Set`, важно знать, +что эти функции не изменяют коллекцию, для которой они вызываются; +вместо этого они возвращают новую коллекцию с обновленными данными. +В результате также принято объединять их вместе в “свободном” стиле для решения проблем. + +Например, в этом примере показано, как отфильтровать коллекцию дважды, +а затем умножить каждый элемент в оставшейся коллекции: + + +{% tabs function_3 %} +{% tab 'Scala 2 and 3' for=function_3 %} +```scala +// пример списка +val nums = (1 to 10).toList // List(1,2,3,4,5,6,7,8,9,10) + +// методы могут быть сцеплены вместе +val x = nums.filter(_ > 3) + .filter(_ < 7) + .map(_ * 10) + +// result: x == List(40, 50, 60) +``` +{% endtab %} +{% endtabs %} + +В дополнение к функциям высшего порядка, используемым в стандартной библиотеке, +вы также можете [создавать свои собственные функции][higher-order]. + +[higher-order]: {% link _overviews/scala3-book/fun-hofs.md %} From de2a482e422bd4a61dd069db58563f10197c0e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 12:29:07 +0300 Subject: [PATCH 07/15] Add taste-objects.md in russian --- _overviews/scala3-book/taste-objects.md | 2 +- _ru/scala3/book/taste-objects.md | 153 ++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-objects.md diff --git a/_overviews/scala3-book/taste-objects.md b/_overviews/scala3-book/taste-objects.md index 0de96664ea..479182bfa2 100644 --- a/_overviews/scala3-book/taste-objects.md +++ b/_overviews/scala3-book/taste-objects.md @@ -2,7 +2,7 @@ title: Singleton Objects type: section description: This section provides an introduction to the use of singleton objects in Scala 3. -languages: [zh-cn] +languages: [ru, zh-cn] num: 12 previous-page: taste-functions next-page: taste-collections diff --git a/_ru/scala3/book/taste-objects.md b/_ru/scala3/book/taste-objects.md new file mode 100644 index 0000000000..75e07a12d5 --- /dev/null +++ b/_ru/scala3/book/taste-objects.md @@ -0,0 +1,153 @@ +--- +layout: multipage-overview +title: Одноэлементные объекты +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: В этом разделе представлено введение в использование одноэлементных объектов в Scala 3. +language: ru +num: 12 +previous-page: taste-functions +next-page: taste-collections +--- + + +В Scala ключевое слово `object` создает объект Singleton (паттерн проектирования "Одиночка"). +Другими словами, объект определяет класс, который имеет только один экземпляр. + +Объекты имеют несколько применений: + +- Они используются для создания коллекций служебных методов. +- _Сопутствующий объект_ — это объект с тем же именем, что и у класса, определенного в этом же файле. + В этой ситуации такой класс также называется _сопутствующим классом_. +- Они используются для реализации трейтов для создания _модулей_. + + +## “Полезные” методы + +Поскольку `object` является "одиночкой", к его методам можно обращаться так же, как к статичным методам в Java классе. +Например, этот объект `StringUtils` содержит небольшой набор методов, связанных со строками: + +{% tabs object_1 class=tabs-scala-version %} +{% tab 'Scala 2' for=object_1 %} +```scala +object StringUtils { + def isNullOrEmpty(s: String): Boolean = s == null || s.trim.isEmpty + def leftTrim(s: String): String = s.replaceAll("^\\s+", "") + def rightTrim(s: String): String = s.replaceAll("\\s+$", "") +} +``` +{% endtab %} + +{% tab 'Scala 3' for=object_1 %} +```scala +object StringUtils: + def isNullOrEmpty(s: String): Boolean = s == null || s.trim.isEmpty + def leftTrim(s: String): String = s.replaceAll("^\\s+", "") + def rightTrim(s: String): String = s.replaceAll("\\s+$", "") +``` +{% endtab %} +{% endtabs %} + +Поскольку `StringUtils` - это "одиночка", его методы можно вызывать непосредственно для объекта: + +{% tabs object_2 %} +{% tab 'Scala 2 and 3' for=object_2 %} +```scala +val x = StringUtils.isNullOrEmpty("") // true +val x = StringUtils.isNullOrEmpty("a") // false +``` +{% endtab %} +{% endtabs %} + +## Сопутствующие объекты + +Сопутствующие класс или объект могут получить доступ к закрытым членам своего компаньона. +Используйте сопутствующий объект для методов и значений, которые не относятся к экземплярам сопутствующего класса. + +В этом примере показано, как метод `area` в сопутствующем классе +может получить доступ к приватному методу `calculateArea` в своем сопутствующем объекте: + +{% tabs object_3 class=tabs-scala-version %} +{% tab 'Scala 2' for=object_3 %} +```scala +import scala.math._ + +class Circle(radius: Double) { + import Circle._ + def area: Double = calculateArea(radius) +} + +object Circle { + private def calculateArea(radius: Double): Double = + Pi * pow(radius, 2.0) +} + +val circle1 = new Circle(5.0) +circle1.area // Double = 78.53981633974483 +``` +{% endtab %} + +{% tab 'Scala 3' for=object_3 %} +```scala +import scala.math.* + +class Circle(radius: Double): + import Circle.* + def area: Double = calculateArea(radius) + +object Circle: + private def calculateArea(radius: Double): Double = + Pi * pow(radius, 2.0) + +val circle1 = Circle(5.0) +circle1.area // Double = 78.53981633974483 +``` +{% endtab %} +{% endtabs %} + +## Создание модулей из трейтов + +Объекты также можно использовать для реализации трейтов для создания модулей. +Эта техника берет две трейта и объединяет их для создания конкретного `object`-а: + +{% tabs object_4 class=tabs-scala-version %} +{% tab 'Scala 2' for=object_4 %} +```scala +trait AddService { + def add(a: Int, b: Int) = a + b +} + +trait MultiplyService { + def multiply(a: Int, b: Int) = a * b +} + +// реализация трейтов выше в качестве конкретного объекта +object MathService extends AddService with MultiplyService + +// использование объекта +import MathService._ +println(add(1,1)) // 2 +println(multiply(2,2)) // 4 +``` +{% endtab %} + +{% tab 'Scala 3' for=object_4 %} +```scala +trait AddService: + def add(a: Int, b: Int) = a + b + +trait MultiplyService: + def multiply(a: Int, b: Int) = a * b + +// реализация трейтов выше в качестве конкретного объекта +object MathService extends AddService, MultiplyService + +// использование объекта +import MathService.* +println(add(1,1)) // 2 +println(multiply(2,2)) // 4 +``` +{% endtab %} +{% endtabs %} From 05aaccba59cef514ce8ff4ae0efdedbd818f2e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 12:47:51 +0300 Subject: [PATCH 08/15] Add taste-collections.md in russian --- _overviews/scala3-book/taste-collections.md | 2 +- _ru/scala3/book/taste-collections.md | 161 ++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-collections.md diff --git a/_overviews/scala3-book/taste-collections.md b/_overviews/scala3-book/taste-collections.md index bcaca071d0..773f823ce4 100644 --- a/_overviews/scala3-book/taste-collections.md +++ b/_overviews/scala3-book/taste-collections.md @@ -2,7 +2,7 @@ title: Collections type: section description: This page provides a high-level overview of the main features of the Scala 3 programming language. -languages: [zh-cn] +languages: [ru, zh-cn] num: 13 previous-page: taste-objects next-page: taste-contextual-abstractions diff --git a/_ru/scala3/book/taste-collections.md b/_ru/scala3/book/taste-collections.md new file mode 100644 index 0000000000..5fc5455c78 --- /dev/null +++ b/_ru/scala3/book/taste-collections.md @@ -0,0 +1,161 @@ +--- +layout: multipage-overview +title: Коллекции +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: На этой странице представлен обзор основных коллекций в Scala 3. +language: ru +num: 13 +previous-page: taste-objects +next-page: taste-contextual-abstractions +--- + + +Библиотека Scala поставляется с богатым набором классов коллекций, и эти классы содержат множество методов. +Классы коллекций доступны как в неизменяемой, так и в изменяемой форме. + +## Создание списков + +Чтобы дать вам представление о том, как они работают, вот несколько примеров, в которых используется класс `List`, +являющийся неизменяемым классом связанного списка. +В этих примерах показаны различные способы создания заполненного `List`: + +{% tabs collection_1 %} +{% tab 'Scala 2 and 3' for=collection_1 %} + +```scala +val a = List(1, 2, 3) // a: List[Int] = List(1, 2, 3) + +// методы Range +val b = (1 to 5).toList // b: List[Int] = List(1, 2, 3, 4, 5) +val c = (1 to 10 by 2).toList // c: List[Int] = List(1, 3, 5, 7, 9) +val e = (1 until 5).toList // e: List[Int] = List(1, 2, 3, 4) +val f = List.range(1, 5) // f: List[Int] = List(1, 2, 3, 4) +val g = List.range(1, 10, 3) // g: List[Int] = List(1, 4, 7) +``` + +{% endtab %} +{% endtabs %} + +## Методы `List` + +В следующих примерах показаны некоторые методы, которые можно вызывать для заполненного списка. +Обратите внимание, что все эти методы являются функциональными, +а это означает, что они не изменяют коллекцию, на которой вызываются, +а вместо этого возвращают новую коллекцию с обновленными элементами. +Результат, возвращаемый каждым выражением, отображается в комментарии к каждой строке: + +{% tabs collection_2 %} +{% tab 'Scala 2 and 3' for=collection_2 %} + +```scala +// a sample list +val a = List(10, 20, 30, 40, 10) // List(10, 20, 30, 40, 10) + +a.drop(2) // List(30, 40, 10) +a.dropWhile(_ < 25) // List(30, 40, 10) +a.filter(_ < 25) // List(10, 20, 10) +a.slice(2,4) // List(30, 40) +a.tail // List(20, 30, 40, 10) +a.take(3) // List(10, 20, 30) +a.takeWhile(_ < 30) // List(10, 20) + +// flatten +val a = List(List(1,2), List(3,4)) +a.flatten // List(1, 2, 3, 4) + +// map, flatMap +val nums = List("one", "two") +nums.map(_.toUpperCase) // List("ONE", "TWO") +nums.flatMap(_.toUpperCase) // List('O', 'N', 'E', 'T', 'W', 'O') +``` + +{% endtab %} +{% endtabs %} + +Эти примеры показывают, как методы “foldLeft” и “reduceLeft” используются +для суммирования значений в последовательности целых чисел: + +{% tabs collection_3 %} +{% tab 'Scala 2 and 3' for=collection_3 %} + +```scala +val firstTen = (1 to 10).toList // List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + +firstTen.reduceLeft(_ + _) // 55 +firstTen.foldLeft(100)(_ + _) // 155 (100 является “начальным” значением) +``` + +{% endtab %} +{% endtabs %} + +Для классов коллекций Scala доступно гораздо больше методов, +и они продемонстрированы в главе ["Коллекции"][collections] и в [API документации][api]. + +## Кортежи + +В Scala _кортеж_ (_tuple_) — это тип, позволяющий легко поместить набор различных типов в один и тот же контейнер. +Например, используя данный case класс `Person`: + +{% tabs collection_4 %} +{% tab 'Scala 2 and 3' for=collection_4 %} + +```scala +case class Person(name: String) +``` + +{% endtab %} +{% endtabs %} + +Вот как вы создаете кортеж, который содержит `Int`, `String` и пользовательское значение `Person`: + +{% tabs collection_5 %} +{% tab 'Scala 2 and 3' for=collection_5 %} + +```scala +val t = (11, "eleven", Person("Eleven")) +``` + +{% endtab %} +{% endtabs %} + +Когда у вас есть кортеж, вы можете получить доступ к его значениям, привязав их к переменным, +или получить к ним доступ по номеру: + +{% tabs collection_6 %} +{% tab 'Scala 2 and 3' for=collection_6 %} + +```scala +t(0) // 11 +t(1) // "eleven" +t(2) // Person("Eleven") +``` + +{% endtab %} +{% endtabs %} + +Вы также можете использовать этот метод _извлечения_, чтобы присвоить поля кортежа именам переменных: + +{% tabs collection_7 %} +{% tab 'Scala 2 and 3' for=collection_7 %} + +```scala +val (num, str, person) = t + +// в результате: +// val num: Int = 11 +// val str: String = eleven +// val person: Person = Person(Eleven) +``` + +{% endtab %} +{% endtabs %} + +Кортежи хороши в тех случаях, когда вы хотите поместить коллекцию разнородных типов в небольшую структуру, похожую на коллекцию. +Дополнительные сведения о кортежах см. ["в справочной документации"][reference]. + +[collections]: {% link _overviews/scala3-book/collections-intro.md %} +[api]: https://scala-lang.org/api/3.x/ +[reference]: {{ site.scala3ref }}/overview.html From 35e3e89ccafb82ec7354715b8ec26788d796271c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 12:50:17 +0300 Subject: [PATCH 09/15] Add taste-contextual-abstractions.md in russian --- .../taste-contextual-abstractions.md | 2 +- .../book/taste-contextual-abstractions.md | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-contextual-abstractions.md diff --git a/_overviews/scala3-book/taste-contextual-abstractions.md b/_overviews/scala3-book/taste-contextual-abstractions.md index 9e25f5029a..60d21d1643 100644 --- a/_overviews/scala3-book/taste-contextual-abstractions.md +++ b/_overviews/scala3-book/taste-contextual-abstractions.md @@ -2,7 +2,7 @@ title: Contextual Abstractions type: section description: This section provides an introduction to Contextual Abstractions in Scala 3. -languages: [zh-cn] +languages: [ru, zh-cn] num: 14 previous-page: taste-collections next-page: taste-toplevel-definitions diff --git a/_ru/scala3/book/taste-contextual-abstractions.md b/_ru/scala3/book/taste-contextual-abstractions.md new file mode 100644 index 0000000000..08930d5dd8 --- /dev/null +++ b/_ru/scala3/book/taste-contextual-abstractions.md @@ -0,0 +1,79 @@ +--- +layout: multipage-overview +title: Контекстные абстракции +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: В этом разделе представлено введение в контекстные абстракции в Scala 3. +language: ru +num: 14 +previous-page: taste-collections +next-page: taste-toplevel-definitions +--- + + +При определенных обстоятельствах вы можете опустить некоторые параметры вызовов методов, которые считаются повторяющимися. + +Эти параметры называются _параметрами контекста_ (_Context Parameters_), +поскольку они выводятся компилятором из контекста, окружающего вызов метода. + +Например, рассмотрим программу, которая сортирует список адресов по двум критериям: +название города, а затем название улицы. + +{% tabs contextual_1 %} +{% tab 'Scala 2 and 3' for=contextual_1 %} + +```scala +val addresses: List[Address] = ... + +addresses.sortBy(address => (address.city, address.street)) +``` + +{% endtab %} +{% endtabs %} + +Метод `sortBy` принимает функцию, которая возвращает для каждого адреса значение, чтобы сравнить его с другими адресами. +В этом случае мы передаем функцию, которая возвращает пару, содержащую название города и название улицы. + +Обратите внимание, что мы только указываем, _что_ сравнивать, но не _как_ выполнять сравнение. +Откуда алгоритм сортировки знает, как сравнивать пары `String`? + +На самом деле метод `sortBy` принимает второй параметр — параметр контекста, который выводится компилятором. +Его нет в приведенном выше примере, поскольку он предоставляется компилятором. + +Этот второй параметр реализует _способ_ сравнения. +Его удобно опустить, потому что мы знаем, что `String`-и обычно сравниваются в лексикографическом порядке. + +Однако также возможно передать параметр явно: + +{% tabs contextual_2 class=tabs-scala-version %} +{% tab 'Scala 2' for=contextual_2 %} + +```scala +addresses.sortBy(address => (address.city, address.street))(Ordering.Tuple2(Ordering.String, Ordering.String)) +``` + +{% endtab %} +{% tab 'Scala 3' for=contextual_2 %} + +```scala +addresses.sortBy(address => (address.city, address.street))(using Ordering.Tuple2(Ordering.String, Ordering.String)) +``` + +в Scala 3 `using` в списке аргументов сигнализирует `sortBy` о явной передаче параметра контекста, избегая двусмысленности. + +{% endtab %} +{% endtabs %} + +В этом случае экземпляр `Ordering.Tuple2(Ordering.String, Ordering.String)` — это именно тот экземпляр, +который в противном случае выводится компилятором. +Другими словами, оба примера создают одну и ту же программу. + +_Контекстные абстракции_ используются, чтобы избежать повторения кода. +Они помогают разработчикам писать фрагменты кода, которые являются расширяемыми и в то же время лаконичными. + +Дополнительные сведения см. в [главе "Контекстные абстракции"][contextual] этой книги, а также в [справочной документации][reference]. + +[contextual]: {% link _overviews/scala3-book/ca-contextual-abstractions-intro.md %} +[reference]: {{ site.scala3ref }}/overview.html From ed0d481009bc718fb7ce5268259dc138d089db2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 13:00:08 +0300 Subject: [PATCH 10/15] Add taste-toplevel-definitions.md in russian --- .../scala3-book/taste-toplevel-definitions.md | 2 +- _ru/scala3/book/taste-toplevel-definitions.md | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-toplevel-definitions.md diff --git a/_overviews/scala3-book/taste-toplevel-definitions.md b/_overviews/scala3-book/taste-toplevel-definitions.md index 7448af41ed..b56273945f 100644 --- a/_overviews/scala3-book/taste-toplevel-definitions.md +++ b/_overviews/scala3-book/taste-toplevel-definitions.md @@ -2,7 +2,7 @@ title: Toplevel Definitions type: section description: This page provides an introduction to top-level definitions in Scala 3 -languages: [zh-cn] +languages: [ru, zh-cn] num: 15 previous-page: taste-contextual-abstractions next-page: taste-summary diff --git a/_ru/scala3/book/taste-toplevel-definitions.md b/_ru/scala3/book/taste-toplevel-definitions.md new file mode 100644 index 0000000000..71f964addd --- /dev/null +++ b/_ru/scala3/book/taste-toplevel-definitions.md @@ -0,0 +1,79 @@ +--- +layout: multipage-overview +title: Верхнеуровневые определения +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: На этой странице представлено введение в определения верхнего уровня в Scala 3. +language: ru +num: 15 +previous-page: taste-contextual-abstractions +next-page: taste-summary +--- + + +В Scala 3 все виды определений могут быть записаны на “верхнем уровне” ваших файлов с исходным кодом. +Например, вы можете создать файл с именем _MyCoolApp.scala_ и поместить в него следующее содержимое: + +{% tabs toplevel_1 %} +{% tab 'Scala 3 only' for=toplevel_1 %} +```scala +import scala.collection.mutable.ArrayBuffer + +enum Topping: + case Cheese, Pepperoni, Mushrooms + +import Topping.* +class Pizza: + val toppings = ArrayBuffer[Topping]() + +val p = Pizza() + +extension (s: String) + def capitalizeAllWords = s.split(" ").map(_.capitalize).mkString(" ") + +val hwUpper = "hello, world".capitalizeAllWords + +type Money = BigDecimal + +// по желанию здесь можно указать ещё больше определений ... + +@main def myApp = + p.toppings += Cheese + println("show me the code".capitalizeAllWords) +``` +{% endtab %} +{% endtabs %} + +Как показано, нет необходимости помещать эти определения внутрь конструкции `package`, `class` или иной конструкции. + +## Заменяет объекты пакета + +Если вы знакомы со Scala 2, этот подход заменяет _объекты пакета_ (_package objects_). +Но, будучи намного проще в использовании, они работают одинаково: +когда вы помещаете определение в пакет с именем `foo`, +вы можете получить доступ к этому определению во всех других пакетах в `foo`, например, в пакете `foo.bar`, +как в этом примере: + +{% tabs toplevel_2 %} +{% tab 'Scala 3 only' for=toplevel_2 %} +```scala +package foo { + def double(i: Int) = i * 2 +} + +package foo { + package bar { + @main def fooBarMain = + println(s"${double(1)}") // это работает + } +} +``` +{% endtab %} +{% endtabs %} + +Фигурные скобки используются в этом примере, чтобы подчеркнуть вложенность пакета. + +Преимуществом такого подхода является то, что можно размещать определения в пакете с именем `com.acme.myapp`, +а затем можно ссылаться на эти определения в `com.acme.myapp.model`, `com.acme.myapp.controller` и т.д. From dae0733582cec0b0a59ea3102a4b4ebd8f1945a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 13:07:27 +0300 Subject: [PATCH 11/15] Add taste-summary.md in russian --- _overviews/scala3-book/taste-summary.md | 2 +- _ru/scala3/book/taste-summary.md | 35 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 _ru/scala3/book/taste-summary.md diff --git a/_overviews/scala3-book/taste-summary.md b/_overviews/scala3-book/taste-summary.md index d04d2db8a4..96c95089c3 100644 --- a/_overviews/scala3-book/taste-summary.md +++ b/_overviews/scala3-book/taste-summary.md @@ -2,7 +2,7 @@ title: Summary type: section description: This page provides a summary of the previous 'Taste of Scala' sections. -languages: [zh-cn] +languages: [ru, zh-cn] num: 16 previous-page: taste-toplevel-definitions next-page: first-look-at-types diff --git a/_ru/scala3/book/taste-summary.md b/_ru/scala3/book/taste-summary.md new file mode 100644 index 0000000000..c8a6dee275 --- /dev/null +++ b/_ru/scala3/book/taste-summary.md @@ -0,0 +1,35 @@ +--- +layout: multipage-overview +title: Обзор +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: На этой странице представлен краткий обзор предыдущих разделов 'Taste of Scala'. +language: ru +num: 16 +previous-page: taste-toplevel-definitions +next-page: first-look-at-types +--- + + +В предыдущих разделах вы видели: + +- Как использовать Scala REPL +- Как создавать переменные с помощью `val` и `var` +- Некоторые распространенные типы данных +- Структуры управления +- Как моделировать реальный мир, используя стили ООП и ФП +- Как создавать и использовать методы +- Как использовать лямбды (анонимные функции) и функции высшего порядка +- Как использовать объекты для нескольких целей +- Введение в [контекстную абстракцию][contextual] + +Мы также упоминали, что если вы предпочитаете использовать игровую среду на основе браузера вместо Scala REPL, +вы также можете использовать [Scastie](https://scastie.scala-lang.org/). + +Scala включает в себя еще больше возможностей, которые не рассматриваются в этом кратком обзоре. +Дополнительную информацию см. в оставшейся части этой книги и [в справочной документации][reference]. + +[reference]: {{ site.scala3ref }}/overview.html +[contextual]: {% link _overviews/scala3-book/ca-contextual-abstractions-intro.md %} From 432ce160c770ceee88f5a45c9d866dcbf0326087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Sat, 12 Nov 2022 13:48:22 +0300 Subject: [PATCH 12/15] Add first-look-at-types.md in russian --- _overviews/scala3-book/first-look-at-types.md | 24 +- _ru/scala3/book/first-look-at-types.md | 355 ++++++++++++++++++ 2 files changed, 367 insertions(+), 12 deletions(-) create mode 100644 _ru/scala3/book/first-look-at-types.md diff --git a/_overviews/scala3-book/first-look-at-types.md b/_overviews/scala3-book/first-look-at-types.md index 479ae136ab..4a822d6edf 100644 --- a/_overviews/scala3-book/first-look-at-types.md +++ b/_overviews/scala3-book/first-look-at-types.md @@ -2,7 +2,7 @@ title: A First Look at Types type: chapter description: This page provides a brief introduction to Scala's built-in data types, including Int, Double, String, Long, Any, AnyRef, Nothing, and Null. -languages: [zh-cn] +languages: [ru, zh-cn] num: 17 previous-page: taste-summary next-page: control-structures @@ -139,17 +139,17 @@ As shown, enclose strings in double-quotes---or triple-quotes for multiline stri Those data types and their ranges are: -| Data Type | Possible Values | -| ------------- | --------------- | -| Boolean | `true` or `false` | -| Byte | 8-bit signed two’s complement integer (-2^7 to 2^7-1, inclusive)
-128 to 127 | -| Short | 16-bit signed two’s complement integer (-2^15 to 2^15-1, inclusive)
-32,768 to 32,767 -| Int | 32-bit two’s complement integer (-2^31 to 2^31-1, inclusive)
-2,147,483,648 to 2,147,483,647 | -| Long | 64-bit two’s complement integer (-2^63 to 2^63-1, inclusive)
(-2^63 to 2^63-1, inclusive) | -| Float | 32-bit IEEE 754 single-precision float
1.40129846432481707e-45 to 3.40282346638528860e+38 | -| Double | 64-bit IEEE 754 double-precision float
4.94065645841246544e-324 to 1.79769313486231570e+308 | -| Char | 16-bit unsigned Unicode character (0 to 2^16-1, inclusive)
0 to 65,535 | -| String | a sequence of `Char` | +| Data Type | Possible Values | +|-----------|--------------------------------------------------------------------------------------------------| +| Boolean | `true` or `false` | +| Byte | 8-bit signed two’s complement integer (-2^7 to 2^7-1, inclusive)
-128 to 127 | +| Short | 16-bit signed two’s complement integer (-2^15 to 2^15-1, inclusive)
-32,768 to 32,767 | +| Int | 32-bit two’s complement integer (-2^31 to 2^31-1, inclusive)
-2,147,483,648 to 2,147,483,647 | +| Long | 64-bit two’s complement integer (-2^63 to 2^63-1, inclusive)
(-2^63 to 2^63-1, inclusive) | +| Float | 32-bit IEEE 754 single-precision float
1.40129846432481707e-45 to 3.40282346638528860e+38 | +| Double | 64-bit IEEE 754 double-precision float
4.94065645841246544e-324 to 1.79769313486231570e+308 | +| Char | 16-bit unsigned Unicode character (0 to 2^16-1, inclusive)
0 to 65,535 | +| String | a sequence of `Char` | ## `BigInt` and `BigDecimal` diff --git a/_ru/scala3/book/first-look-at-types.md b/_ru/scala3/book/first-look-at-types.md new file mode 100644 index 0000000000..603157c6d1 --- /dev/null +++ b/_ru/scala3/book/first-look-at-types.md @@ -0,0 +1,355 @@ +--- +layout: multipage-overview +title: Первый взгляд на типы +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: На этой странице представлено краткое введение во встроенные типы данных Scala, включая Int, Double, String, Long, Any, AnyRef, Nothing и Null. +language: ru +num: 17 +previous-page: taste-summary +next-page: +--- + + +## Все значения имеют тип + +В Scala все значения имеют тип, включая числовые значения и функции. +На приведенной ниже диаграмме показано подмножество иерархии типов. + +Scala 3 Type Hierarchy + +## Иерархия типов Scala + +`Any` - это супертип всех типов, также называемый **верхним типом** (**the top type**). +Он определяет универсальные методы, такие как `equals`, `hashCode` и `toString`. + +У верхнего типа `Any` есть подтип [`Matchable`][matchable], который используется для обозначения всех типов, +для которых возможно выполнить pattern matching (сопоставление с образцом). +Важно гарантировать вызов свойства _“параметричность”_, что вкратце означает, +что мы не можем сопоставлять шаблоны для значений типа `Any`, а только для значений, которые являются подтипом `Matchable`. +[Справочная документация][matchable] содержит более подробную информацию о `Matchable`. + +`Matchable` содержит два важных подтипа: `AnyVal` и `AnyRef`. + +*`AnyVal`* представляет типы значений. +Существует несколько предопределенных типов значений, и они non-nullable: +`Double`, `Float`, `Long`, `Int`, `Short`, `Byte`, `Char`, `Unit` и `Boolean`. +`Unit` - это тип значения, который не несет никакой значимой информации. Существует ровно один экземпляр `Unit` - `()`. + +*`AnyRef`* представляет ссылочные типы. Все типы, не являющиеся значениями, определяются как ссылочные типы. +Каждый пользовательский тип в Scala является подтипом `AnyRef`. +Если Scala используется в контексте среды выполнения Java, `AnyRef` соответствует `java.lang.Object`. + +В языках, основанных на операторах, `void` используется для методов, которые ничего не возвращают. +В Scala для методов, которые не имеют возвращаемого значения, +такие как следующий метод, для той же цели используется `Unit`: + +{% tabs unit %} +{% tab 'Scala 2 and 3' for=unit %} +```scala +def printIt(a: Any): Unit = println(a) +``` +{% endtab %} +{% endtabs %} + +Вот пример, демонстрирующий, что строки, целые числа, символы, логические значения и функции являются экземплярами `Any` +и могут обрабатываться так же, как и любой другой объект: + +{% tabs any %} +{% tab 'Scala 2 and 3' for=any %} +```scala +val list: List[Any] = List( + "a string", + 732, // число + 'c', // буква + true, // булево значение + () => "an anonymous function returning a string" +) + +list.foreach(element => println(element)) +``` +{% endtab %} +{% endtabs %} + +Код определяет список значений типа `List[Any]`. +Список инициализируется элементами различных типов, но каждый из них является экземпляром `scala.Any`, +поэтому мы можем добавить их в список. + +Вот вывод программы: + +``` +a string +732 +c +true + +``` + +## Типы значений в Scala + +Как показано выше, числовые типы Scala расширяют `AnyVal`, и все они являются полноценными объектами. +В этих примерах показано, как объявлять переменные этих числовых типов: + +{% tabs anyval %} +{% tab 'Scala 2 and 3' for=anyval %} +```scala +val b: Byte = 1 +val i: Int = 1 +val l: Long = 1 +val s: Short = 1 +val d: Double = 2.0 +val f: Float = 3.0 +``` +{% endtab %} +{% endtabs %} + +В первых четырех примерах, если явно не указать тип, то тип числа `1` по умолчанию будет равен `Int`, +поэтому, если нужен один из других типов данных — `Byte`, `Long` или `Short` — необходимо явно объявить эти типы. +Числа с десятичной дробью (например, `2.0`) по умолчанию будут иметь тип `Double`, +поэтому, если необходим `Float`, нужно объявить `Float` явно, как показано в последнем примере. + +Поскольку `Int` и `Double` являются числовыми типами по умолчанию, их можно создавать без явного объявления типа данных: + +{% tabs anynum %} +{% tab 'Scala 2 and 3' for=anynum %} +```scala +val i = 123 // по умолчанию Int +val x = 1.0 // по умолчанию Double +``` +{% endtab %} +{% endtabs %} + +Также можно добавить символы `L`, `D`, and `F` (или их эквивалент в нижнем регистре) +для того, чтобы задать `Long`, `Double` или `Float` значения: + +{% tabs type-post %} +{% tab 'Scala 2 and 3' for=type-post %} +```scala +val x = 1_000L // val x: Long = 1000 +val y = 2.2D // val y: Double = 2.2 +val z = 3.3F // val z: Float = 3.3 +``` +{% endtab %} +{% endtabs %} + +В Scala также есть типы `String` и `Char`, которые обычно можно объявить в неявной форме: + +{% tabs type-string %} +{% tab 'Scala 2 and 3' for=type-string %} +```scala +val s = "Bill" +val c = 'a' +``` +{% endtab %} +{% endtabs %} + +Как показано, заключайте строки в двойные кавычки или тройные кавычки для многострочных строк, +а одиночный символ заключайте в одинарные кавычки. + +Типы данных и их диапазоны: + +| Тип данных | Возможные значения | +|------------|--------------------------------------------------------------------------------------------------------------------------------| +| Boolean | `true` или `false` | +| Byte | 8-битное целое число в дополнении до двух со знаком (от -2^7 до 2^7-1 включительно)
от -128 до 127 | +| Short | 16-битное целое число в дополнении до двух со знаком (от -2^15 до 2^15-1 включительно)
от -32 768 до 32 767 | +| Int | 32-битное целое число с дополнением до двух со знаком (от -2^31 до 2^31-1 включительно)
от -2 147 483 648 до 2 147 483 647 | +| Long | 64-битное целое число с дополнением до двух со знаком (от -2^63 до 2^63-1 включительно)
(от -2^63 до 2^63-1 включительно) | +| Float | 32-разрядный IEEE 754 одинарной точности с плавающей точкой
от 1,40129846432481707e-45 до 3,40282346638528860e+38 | +| Double | 64-битный IEEE 754 двойной точности с плавающей запятой
от 4,94065645841246544e-324 до 1,79769313486231570e+308 | +| Char | 16-битный символ Unicode без знака (от 0 до 2^16-1 включительно)
от 0 до 65 535 | +| String | последовательность `Char` | + + +## `BigInt` и `BigDecimal` + +Для действительно больших чисел можно использовать типы `BigInt` и `BigDecimal`: + +{% tabs type-bigint %} +{% tab 'Scala 2 and 3' for=type-bigint %} +```scala +val a = BigInt(1_234_567_890_987_654_321L) +val b = BigDecimal(123_456.789) +``` +{% endtab %} +{% endtabs %} + +Где `Double` и `Float` являются приблизительными десятичными числами, +а `BigDecimal` используется для точной арифметики, например, при работе с валютой. + +`BigInt` и `BigDecimal` поддерживают все привычные числовые операторы: + +{% tabs type-bigint2 %} +{% tab 'Scala 2 and 3' for=type-bigint2 %} +```scala +val b = BigInt(1234567890) // scala.math.BigInt = 1234567890 +val c = b + b // scala.math.BigInt = 2469135780 +val d = b * b // scala.math.BigInt = 1524157875019052100 +``` +{% endtab %} +{% endtabs %} + +## Два замечания о строках + +Строки Scala похожи на строки Java, но у них есть две замечательные дополнительные функции: + +- Они поддерживают интерполяцию строк +- Легко создавать многострочные строки + +### Интерполяция строк + +Интерполяция строк обеспечивает очень удобный способ использования переменных внутри строк. +Например, учитывая эти три переменные: + +{% tabs string-inside1 %} +{% tab 'Scala 2 and 3' for=string-inside1 %} +```scala +val firstName = "John" +val mi = 'C' +val lastName = "Doe" +``` +{% endtab %} +{% endtabs %} + +их комбинацию можно получить так: + +{% tabs string-inside2 %} +{% tab 'Scala 2 and 3' for=string-inside2 %} +```scala +println(s"Name: $firstName $mi $lastName") // "Name: John C Doe" +``` +{% endtab %} +{% endtabs %} + +Достаточно поставить перед строкой букву `s`, а затем - символ `$` перед именами переменных внутри строки. + +Чтобы вставить произвольные выражения в строку, они заключаются в фигурные скобки: + +{% tabs string-inside3 %} +{% tab 'Scala 2 and 3' for=string-inside3 %} +```scala +println(s"2 + 2 = ${2 + 2}") // печатает "2 + 2 = 4" +val x = -1 +println(s"x.abs = ${x.abs}") // печатает "x.abs = 1" +``` +{% endtab %} +{% endtabs %} + +#### Другие интерполяторы + +То `s`, что вы помещаете перед строкой, является лишь одним из возможных интерполяторов. +Если вы используете `f` вместо `s`, вы можете использовать `printf` - синтаксис форматирования стиля в строке. +Кроме того, строковый интерполятор — это всего лишь специальный метод, и вы можете определить свой собственный. +Например, некоторые библиотеки баз данных определяют очень мощный интерполятор `sql`. + +### Многострочные строки + +Многострочные строки создаются путем включения строки в три двойные кавычки: + +{% tabs string-mlines1 %} +{% tab 'Scala 2 and 3' for=string-mlines1 %} +```scala +val quote = """The essence of Scala: + Fusion of functional and object-oriented + programming in a typed setting.""" +``` +{% endtab %} +{% endtabs %} + +Одним из недостатков базового подхода является то, что строки после первой имеют отступ. + +{% tabs string-mlines2 %} +{% tab 'Scala 2 and 3' for=string-mlines2 %} +```scala +"The essence of Scala: + Fusion of functional and object-oriented + programming in a typed setting." +``` +{% endtab %} +{% endtabs %} + +Если важно исключить отступ, можно поставить символ `|` перед всеми строками после первой и вызвать метод `stripMargin` после строки: + +{% tabs string-mlines3 %} +{% tab 'Scala 2 and 3' for=string-mlines3 %} +```scala +val quote = """The essence of Scala: + |Fusion of functional and object-oriented + |programming in a typed setting.""".stripMargin +``` +{% endtab %} +{% endtabs %} + +Теперь все строки выравниваются по левому краю: + +{% tabs string-mlines4 %} +{% tab 'Scala 2 and 3' for=string-mlines4 %} +```scala +"The essence of Scala: +Fusion of functional and object-oriented +programming in a typed setting." +``` +{% endtab %} +{% endtabs %} + +## Приведение типов + +Типы значений могут быть приведены следующим образом: + +Scala Type Hierarchy + +Например: + +{% tabs cast1 %} +{% tab 'Scala 2 and 3' for=cast1 %} +```scala +val b: Byte = 127 +val i: Int = b // 127 + +val face: Char = '☺' +val number: Int = face // 9786 +``` +{% endtab %} +{% endtabs %} + +Вы можете привести к типу, только если нет потери информации. +В противном случае вам нужно четко указать приведение типов: + +{% tabs cast2 %} +{% tab 'Scala 2 and 3' for=cast2 %} +```scala +val x: Long = 987654321 +val y: Float = x.toFloat // 9.8765434E8 (обратите внимание, что требуется `.toFloat`, потому что приведение приводит к потере точности) +val z: Long = y // Ошибка +``` +{% endtab %} +{% endtabs %} + +Вы также можете привести ссылочный тип к подтипу. +Это будет рассмотрено в книге позже. + +## `Nothing` и `null` + +`Nothing` является подтипом всех типов, также называемым **нижним типом** (**the bottom type**). +Нет значения, которое имело бы тип `Nothing`. +Он обычно сигнализирует о прекращении, таком как thrown exception, выходе из программы или бесконечном цикле - +т.е. это тип выражения, который не вычисляется до определенного значения, или метод, который нормально не возвращается. + +`Null` - это подтип всех ссылочных типов (т.е. любой подтип `AnyRef`). +Он имеет единственное значение, определяемое ключевым словом `null`. +В настоящее время применение `null` считается плохой практикой. +Его следует использовать в основном для взаимодействия с другими языками JVM. +Опция компилятора `opt-in` изменяет статус `Null`, делая все ссылочные типы non-nullable. +Этот параметр может [стать значением по умолчанию][safe-null] в будущей версии Scala. + +В то же время `null` почти никогда не следует использовать в коде Scala. +Альтернативы `null` обсуждаются в главе о [функциональном программировании][fp] и в [документации API][option-api]. + +[reference]: {{ site.scala3ref }}/overview.html +[matchable]: {{ site.scala3ref }}/other-new-features/matchable.html +[interpolation]: {% link _overviews/core/string-interpolation.md %} +[fp]: {% link _overviews/scala3-book/fp-intro.md %} +[option-api]: https://scala-lang.org/api/3.x/scala/Option.html +[safe-null]: {{ site.scala3ref }}/experimental/explicit-nulls.html From f112d1da818622430bf5ae366eec85d32b040722 Mon Sep 17 00:00:00 2001 From: Artem Korsakov Date: Mon, 14 Nov 2022 21:35:46 +0300 Subject: [PATCH 13/15] Update _ru/scala3/book/taste-repl.md Co-authored-by: Jamie Thompson --- _ru/scala3/book/taste-repl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ru/scala3/book/taste-repl.md b/_ru/scala3/book/taste-repl.md index 40f4c98808..3d35bb9d55 100644 --- a/_ru/scala3/book/taste-repl.md +++ b/_ru/scala3/book/taste-repl.md @@ -4,7 +4,7 @@ title: REPL scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: В этом разделе представлено введение в Scala REPL. language: ru num: 6 From 6fc30cf4ca1caabd055d2f6b45abe8cc2c6d1949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Mon, 14 Nov 2022 21:37:49 +0300 Subject: [PATCH 14/15] Fix the comment --- _ru/scala3/book/taste-collections.md | 2 +- _ru/scala3/book/taste-contextual-abstractions.md | 2 +- _ru/scala3/book/taste-control-structures.md | 2 +- _ru/scala3/book/taste-functions.md | 2 +- _ru/scala3/book/taste-hello-world.md | 2 +- _ru/scala3/book/taste-methods.md | 2 +- _ru/scala3/book/taste-modeling.md | 2 +- _ru/scala3/book/taste-objects.md | 2 +- _ru/scala3/book/taste-summary.md | 2 +- _ru/scala3/book/taste-toplevel-definitions.md | 2 +- _ru/scala3/book/taste-vars-data-types.md | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/_ru/scala3/book/taste-collections.md b/_ru/scala3/book/taste-collections.md index 5fc5455c78..2585f24d20 100644 --- a/_ru/scala3/book/taste-collections.md +++ b/_ru/scala3/book/taste-collections.md @@ -4,7 +4,7 @@ title: Коллекции scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: На этой странице представлен обзор основных коллекций в Scala 3. language: ru num: 13 diff --git a/_ru/scala3/book/taste-contextual-abstractions.md b/_ru/scala3/book/taste-contextual-abstractions.md index 08930d5dd8..80d5e9e3a1 100644 --- a/_ru/scala3/book/taste-contextual-abstractions.md +++ b/_ru/scala3/book/taste-contextual-abstractions.md @@ -4,7 +4,7 @@ title: Контекстные абстракции scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: В этом разделе представлено введение в контекстные абстракции в Scala 3. language: ru num: 14 diff --git a/_ru/scala3/book/taste-control-structures.md b/_ru/scala3/book/taste-control-structures.md index a25efe0db9..0a3559fc21 100644 --- a/_ru/scala3/book/taste-control-structures.md +++ b/_ru/scala3/book/taste-control-structures.md @@ -4,7 +4,7 @@ title: Структуры управления scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: Этот раздел демонстрирует структуры управления в Scala 3. language: ru num: 8 diff --git a/_ru/scala3/book/taste-functions.md b/_ru/scala3/book/taste-functions.md index 6e8c44b50d..207e154931 100644 --- a/_ru/scala3/book/taste-functions.md +++ b/_ru/scala3/book/taste-functions.md @@ -4,7 +4,7 @@ title: Функции первого класса scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: На этой странице представлено введение в функции в Scala 3. language: ru num: 11 diff --git a/_ru/scala3/book/taste-hello-world.md b/_ru/scala3/book/taste-hello-world.md index e96ab3511d..29a59ae763 100644 --- a/_ru/scala3/book/taste-hello-world.md +++ b/_ru/scala3/book/taste-hello-world.md @@ -4,7 +4,7 @@ title: Пример 'Hello, World!' scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: В этом примере демонстрируется пример 'Hello, World!' на Scala 3. language: ru num: 5 diff --git a/_ru/scala3/book/taste-methods.md b/_ru/scala3/book/taste-methods.md index f624ac71c5..87169991f4 100644 --- a/_ru/scala3/book/taste-methods.md +++ b/_ru/scala3/book/taste-methods.md @@ -4,7 +4,7 @@ title: Методы scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: В этом разделе представлено введение в определение и использование методов в Scala 3. language: ru num: 10 diff --git a/_ru/scala3/book/taste-modeling.md b/_ru/scala3/book/taste-modeling.md index 1dbe0c9a51..b50ac31aaf 100644 --- a/_ru/scala3/book/taste-modeling.md +++ b/_ru/scala3/book/taste-modeling.md @@ -4,7 +4,7 @@ title: Моделирование данных scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: В этом разделе представлено введение в моделирование данных в Scala 3. language: ru num: 9 diff --git a/_ru/scala3/book/taste-objects.md b/_ru/scala3/book/taste-objects.md index 75e07a12d5..14c2d79229 100644 --- a/_ru/scala3/book/taste-objects.md +++ b/_ru/scala3/book/taste-objects.md @@ -4,7 +4,7 @@ title: Одноэлементные объекты scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: В этом разделе представлено введение в использование одноэлементных объектов в Scala 3. language: ru num: 12 diff --git a/_ru/scala3/book/taste-summary.md b/_ru/scala3/book/taste-summary.md index c8a6dee275..f2ca4e86da 100644 --- a/_ru/scala3/book/taste-summary.md +++ b/_ru/scala3/book/taste-summary.md @@ -4,7 +4,7 @@ title: Обзор scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: На этой странице представлен краткий обзор предыдущих разделов 'Taste of Scala'. language: ru num: 16 diff --git a/_ru/scala3/book/taste-toplevel-definitions.md b/_ru/scala3/book/taste-toplevel-definitions.md index 71f964addd..c0bac88150 100644 --- a/_ru/scala3/book/taste-toplevel-definitions.md +++ b/_ru/scala3/book/taste-toplevel-definitions.md @@ -4,7 +4,7 @@ title: Верхнеуровневые определения scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: На этой странице представлено введение в определения верхнего уровня в Scala 3. language: ru num: 15 diff --git a/_ru/scala3/book/taste-vars-data-types.md b/_ru/scala3/book/taste-vars-data-types.md index 09451765a4..ab848966d0 100644 --- a/_ru/scala3/book/taste-vars-data-types.md +++ b/_ru/scala3/book/taste-vars-data-types.md @@ -4,7 +4,7 @@ title: Переменные и типы данных scala3: true partof: scala3-book overview-name: "Scala 3 — Book" -type: chapter +type: section description: В этом разделе демонстрируются переменные val и var, а также некоторые распространенные типы данных Scala. language: ru num: 7 From 44b628c7a19db307f6138bf60ed12b63d136345a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC?= Date: Tue, 15 Nov 2022 08:41:02 +0300 Subject: [PATCH 15/15] Fix the comment --- _includes/sidebar-toc-multipage-overview.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/_includes/sidebar-toc-multipage-overview.html b/_includes/sidebar-toc-multipage-overview.html index 5511d96361..c792533ad9 100644 --- a/_includes/sidebar-toc-multipage-overview.html +++ b/_includes/sidebar-toc-multipage-overview.html @@ -21,8 +21,11 @@
Contents
{% assign localizedId = pg.id %} {% for lpg in site.[page.language] %} {% if lpg.id == localizedId %} -
  • {{ lpg.title }} - {{ toc }}
  • + {% if pg.type %} +
  • {{ lpg.title }}{{ toc }}
  • + {% else %} +
  • {{ lpg.title }}{{ toc }}
  • + {% endif %} {% endif %} {% endfor %} {% else %}