diff --git a/_overviews/scala3-book/string-interpolation.md b/_overviews/scala3-book/string-interpolation.md index 7cfdc52369..cf68d4eafd 100644 --- a/_overviews/scala3-book/string-interpolation.md +++ b/_overviews/scala3-book/string-interpolation.md @@ -2,7 +2,7 @@ title: String Interpolation type: chapter description: This page provides more information about creating strings and using string interpolation. -languages: [] +languages: [ru] num: 18 previous-page: first-look-at-types next-page: control-structures diff --git a/_ru/scala3/book/collections-classes.md b/_ru/scala3/book/collections-classes.md index 53f169249f..80fcf30248 100644 --- a/_ru/scala3/book/collections-classes.md +++ b/_ru/scala3/book/collections-classes.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице представлены общие типы коллекций Scala 3 и некоторые из их методов. language: ru -num: 37 +num: 38 previous-page: collections-intro next-page: collections-methods --- diff --git a/_ru/scala3/book/collections-intro.md b/_ru/scala3/book/collections-intro.md index 92793002fe..c29c5ecc29 100644 --- a/_ru/scala3/book/collections-intro.md +++ b/_ru/scala3/book/collections-intro.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: chapter description: На этой странице представлено введение в общие классы коллекций и их методы в Scala 3. language: ru -num: 36 +num: 37 previous-page: packaging-imports next-page: collections-classes --- diff --git a/_ru/scala3/book/collections-methods.md b/_ru/scala3/book/collections-methods.md index 503b52d705..a11cdd1738 100644 --- a/_ru/scala3/book/collections-methods.md +++ b/_ru/scala3/book/collections-methods.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице показаны общие методы классов коллекций Scala 3. language: ru -num: 38 +num: 39 previous-page: collections-classes next-page: collections-summary --- diff --git a/_ru/scala3/book/collections-summary.md b/_ru/scala3/book/collections-summary.md index 6e852ad359..7d89b4961c 100644 --- a/_ru/scala3/book/collections-summary.md +++ b/_ru/scala3/book/collections-summary.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице представлен краткий итог главы «Коллекции». language: ru -num: 39 +num: 40 previous-page: collections-methods next-page: fp-intro --- diff --git a/_ru/scala3/book/control-structures.md b/_ru/scala3/book/control-structures.md index 37e78c1633..fe9c7e4758 100644 --- a/_ru/scala3/book/control-structures.md +++ b/_ru/scala3/book/control-structures.md @@ -7,8 +7,8 @@ overview-name: "Scala 3 — Book" type: chapter description: На этой странице представлено введение в структуры управления Scala, включая if/then/else, циклы for, выражения for, выражения match, try/catch/finally и циклы while. language: ru -num: 18 -previous-page: first-look-at-types +num: 19 +previous-page: string-interpolation next-page: domain-modeling-intro --- diff --git a/_ru/scala3/book/domain-modeling-fp.md b/_ru/scala3/book/domain-modeling-fp.md index e085a0dc06..a5bdb326c5 100644 --- a/_ru/scala3/book/domain-modeling-fp.md +++ b/_ru/scala3/book/domain-modeling-fp.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этой главе представлено введение в моделирование предметной области с использованием ФП в Scala 3. language: ru -num: 22 +num: 23 previous-page: domain-modeling-oop next-page: methods-intro --- diff --git a/_ru/scala3/book/domain-modeling-intro.md b/_ru/scala3/book/domain-modeling-intro.md index 6202dec08d..79828b6d84 100644 --- a/_ru/scala3/book/domain-modeling-intro.md +++ b/_ru/scala3/book/domain-modeling-intro.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: chapter description: В этой главе показано, как можно моделировать предметную область с помощью Scala 3. language: ru -num: 19 +num: 20 previous-page: control-structures next-page: domain-modeling-tools --- diff --git a/_ru/scala3/book/domain-modeling-oop.md b/_ru/scala3/book/domain-modeling-oop.md index df09cdbdd2..f9de517ddd 100644 --- a/_ru/scala3/book/domain-modeling-oop.md +++ b/_ru/scala3/book/domain-modeling-oop.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этой главе представлено введение в моделирование предметной области с использованием ООП в Scala 3. language: ru -num: 21 +num: 22 previous-page: domain-modeling-tools next-page: domain-modeling-fp --- diff --git a/_ru/scala3/book/domain-modeling-tools.md b/_ru/scala3/book/domain-modeling-tools.md index b081a12d2a..ec35430443 100644 --- a/_ru/scala3/book/domain-modeling-tools.md +++ b/_ru/scala3/book/domain-modeling-tools.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этой главе представлено введение в доступные инструменты моделирования предметной области в Scala 3, включая классы, трейты, перечисления и многое другое. language: ru -num: 20 +num: 21 previous-page: domain-modeling-intro next-page: domain-modeling-oop --- diff --git a/_ru/scala3/book/first-look-at-types.md b/_ru/scala3/book/first-look-at-types.md index a0170478f5..5873df07f7 100644 --- a/_ru/scala3/book/first-look-at-types.md +++ b/_ru/scala3/book/first-look-at-types.md @@ -9,10 +9,9 @@ description: На этой странице представлено кратк language: ru num: 17 previous-page: taste-summary -next-page: control-structures +next-page: string-interpolation --- - ## Все значения имеют тип В Scala все значения имеют тип, включая числовые значения и функции. @@ -33,12 +32,12 @@ next-page: control-structures `Matchable` содержит два важных подтипа: `AnyVal` и `AnyRef`. -*`AnyVal`* представляет типы значений. +_`AnyVal`_ представляет типы значений. Существует несколько предопределенных типов значений, и они non-nullable: `Double`, `Float`, `Long`, `Int`, `Short`, `Byte`, `Char`, `Unit` и `Boolean`. `Unit` - это тип значения, который не несет никакой значимой информации. Существует ровно один экземпляр `Unit` - `()`. -*`AnyRef`* представляет ссылочные типы. Все типы, не являющиеся значениями, определяются как ссылочные типы. +_`AnyRef`_ представляет ссылочные типы. Все типы, не являющиеся значениями, определяются как ссылочные типы. Каждый пользовательский тип в Scala является подтипом `AnyRef`. Если Scala используется в контексте среды выполнения Java, `AnyRef` соответствует `java.lang.Object`. @@ -48,9 +47,11 @@ next-page: control-structures {% tabs unit %} {% tab 'Scala 2 и 3' for=unit %} + ```scala def printIt(a: Any): Unit = println(a) ``` + {% endtab %} {% endtabs %} @@ -59,17 +60,20 @@ def printIt(a: Any): Unit = println(a) {% tabs any %} {% tab 'Scala 2 и 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 %} @@ -83,6 +87,7 @@ list.foreach(element => println(element)) a string 732 c +' true ``` @@ -94,6 +99,7 @@ true {% tabs anyval %} {% tab 'Scala 2 и 3' for=anyval %} + ```scala val b: Byte = 1 val i: Int = 1 @@ -102,6 +108,7 @@ val s: Short = 1 val d: Double = 2.0 val f: Float = 3.0 ``` + {% endtab %} {% endtabs %} @@ -114,10 +121,12 @@ val f: Float = 3.0 {% tabs anynum %} {% tab 'Scala 2 и 3' for=anynum %} + ```scala val i = 123 // по умолчанию Int val x = 1.0 // по умолчанию Double ``` + {% endtab %} {% endtabs %} @@ -126,11 +135,30 @@ val x = 1.0 // по умолчанию Double {% tabs type-post %} {% tab 'Scala 2 и 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 +val z = -3.3F // val z: Float = -3.3 ``` + +Вы также можете использовать шестнадцатеричное представление для форматирования целых чисел +(обычно это `Int`, но также поддерживается суффикс `L` для указания `Long`): + +```scala +val a = 0xACE // val a: Int = 2766 +val b = 0xfd_3aL // val b: Long = 64826 +``` + +Scala поддерживает множество различных способов форматирования одного и того же числа с плавающей запятой, +например: + +```scala +val q = .25 // val q: Double = 0.25 +val r = 2.5e-1 // val r: Double = 0.25 +val s = .0025e2F // val s: Float = 0.25 +``` + {% endtab %} {% endtabs %} @@ -138,10 +166,12 @@ val z = 3.3F // val z: Float = 3.3 {% tabs type-string %} {% tab 'Scala 2 и 3' for=type-string %} + ```scala val s = "Bill" val c = 'a' ``` + {% endtab %} {% endtabs %} @@ -151,7 +181,7 @@ val c = 'a' Типы данных и их диапазоны: | Тип данных | Возможные значения | -|------------|--------------------------------------------------------------------------------------------------------------------------------| +| ---------- | ------------------------------------------------------------------------------------------------------------------------------ | | Boolean | `true` или `false` | | Byte | 8-битное целое число в дополнении до двух со знаком (от -2^7 до 2^7-1 включительно)
от -128 до 127 | | Short | 16-битное целое число в дополнении до двух со знаком (от -2^15 до 2^15-1 включительно)
от -32 768 до 32 767 | @@ -162,135 +192,100 @@ val c = 'a' | Char | 16-битный символ Unicode без знака (от 0 до 2^16-1 включительно)
от 0 до 65 535 | | String | последовательность `Char` | +## Строки -## `BigInt` и `BigDecimal` +Строки Scala похожи на строки Java, +хотя в отличие от Java (по крайней мере, до Java 15) +в Scala легко создавать многострочные строки с тройными кавычками: -Для действительно больших чисел можно использовать типы `BigInt` и `BigDecimal`: +{% tabs string-mlines1 %} +{% tab 'Scala 2 и 3' for=string-mlines1 %} -{% tabs type-bigint %} -{% tab 'Scala 2 и 3' for=type-bigint %} ```scala -val a = BigInt(1_234_567_890_987_654_321L) -val b = BigDecimal(123_456.789) +val quote = """The essence of Scala: + Fusion of functional and object-oriented + programming in a typed setting.""" ``` + {% endtab %} {% endtabs %} -Где `Double` и `Float` являются приблизительными десятичными числами, -а `BigDecimal` используется для точной арифметики, например, при работе с валютой. +Одним из недостатков этого базового подхода является то, +что строки после первой строки содержат отступ и выглядят следующим образом: -`BigInt` и `BigDecimal` поддерживают все привычные числовые операторы: +{% tabs string-mlines2 %} +{% tab 'Scala 2 и 3' for=string-mlines2 %} -{% tabs type-bigint2 %} -{% tab 'Scala 2 и 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 +"The essence of Scala: + Fusion of functional and object-oriented + programming in a typed setting." ``` + {% endtab %} {% endtabs %} -## Два замечания о строках - -Строки Scala похожи на строки Java, но у них есть две замечательные дополнительные функции: +Если важно исключить отступ, можно поставить символ `|` перед всеми строками после первой +и вызвать метод `stripMargin` после строки: -- Они поддерживают интерполяцию строк -- Легко создавать многострочные строки - -### Интерполяция строк - -Интерполяция строк обеспечивает очень удобный способ использования переменных внутри строк. -Например, учитывая эти три переменные: +{% tabs string-mlines3 %} +{% tab 'Scala 2 и 3' for=string-mlines3 %} -{% tabs string-inside1 %} -{% tab 'Scala 2 и 3' for=string-inside1 %} ```scala -val firstName = "John" -val mi = 'C' -val lastName = "Doe" +val quote = """The essence of Scala: + |Fusion of functional and object-oriented + |programming in a typed setting.""".stripMargin ``` -{% endtab %} -{% endtabs %} - -их комбинацию можно получить так: -{% tabs string-inside2 %} -{% tab 'Scala 2 и 3' for=string-inside2 %} -```scala -println(s"Name: $firstName $mi $lastName") // "Name: John C Doe" -``` {% endtab %} {% endtabs %} -Достаточно поставить перед строкой букву `s`, а затем - символ `$` перед именами переменных внутри строки. +Теперь все строки выравниваются по левому краю: -Чтобы вставить произвольные выражения в строку, они заключаются в фигурные скобки: +{% tabs string-mlines4 %} +{% tab 'Scala 2 и 3' for=string-mlines4 %} -{% tabs string-inside3 %} -{% tab 'Scala 2 и 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" +"The essence of Scala: +Fusion of functional and object-oriented +programming in a typed setting." ``` + {% endtab %} {% endtabs %} -#### Другие интерполяторы +Строки Scala также поддерживают мощные методы интерполяции строк, +о которых мы поговорим [в следующей главе][string-interpolation]. -То `s`, что вы помещаете перед строкой, является лишь одним из возможных интерполяторов. -Если вы используете `f` вместо `s`, вы можете использовать `printf` - синтаксис форматирования стиля в строке. -Кроме того, строковый интерполятор — это всего лишь специальный метод, и вы можете определить свой собственный. -Например, некоторые библиотеки баз данных определяют очень мощный интерполятор `sql`. +## `BigInt` и `BigDecimal` -### Многострочные строки +Для действительно больших чисел можно использовать типы `BigInt` и `BigDecimal`: -Многострочные строки создаются путем включения строки в три двойные кавычки: +{% tabs type-bigint %} +{% tab 'Scala 2 и 3' for=type-bigint %} -{% tabs string-mlines1 %} -{% tab 'Scala 2 и 3' for=string-mlines1 %} ```scala -val quote = """The essence of Scala: - Fusion of functional and object-oriented - programming in a typed setting.""" +val a = BigInt(1_234_567_890_987_654_321L) +val b = BigDecimal(123456.789) ``` -{% endtab %} -{% endtabs %} - -Одним из недостатков базового подхода является то, что строки после первой имеют отступ. -{% tabs string-mlines2 %} -{% tab 'Scala 2 и 3' for=string-mlines2 %} -```scala -"The essence of Scala: - Fusion of functional and object-oriented - programming in a typed setting." -``` {% endtab %} {% endtabs %} -Если важно исключить отступ, можно поставить символ `|` перед всеми строками после первой и вызвать метод `stripMargin` после строки: +Где `Double` и `Float` являются приблизительными десятичными числами, +а `BigDecimal` используется для точной арифметики, например, при работе с валютой. -{% tabs string-mlines3 %} -{% tab 'Scala 2 и 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 %} +`BigInt` и `BigDecimal` поддерживают все привычные числовые операторы: -Теперь все строки выравниваются по левому краю: +{% tabs type-bigint2 %} +{% tab 'Scala 2 и 3' for=type-bigint2 %} -{% tabs string-mlines4 %} -{% tab 'Scala 2 и 3' for=string-mlines4 %} ```scala -"The essence of Scala: -Fusion of functional and object-oriented -programming in a typed setting." +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 %} @@ -304,6 +299,7 @@ programming in a typed setting." {% tabs cast1 %} {% tab 'Scala 2 и 3' for=cast1 %} + ```scala val b: Byte = 127 val i: Int = b // 127 @@ -311,6 +307,7 @@ val i: Int = b // 127 val face: Char = '☺' val number: Int = face // 9786 ``` + {% endtab %} {% endtabs %} @@ -319,11 +316,13 @@ val number: Int = face // 9786 {% tabs cast2 %} {% tab 'Scala 2 и 3' for=cast2 %} + ```scala val x: Long = 987654321 val y: Float = x.toFloat // 9.8765434E8 (обратите внимание, что требуется `.toFloat`, потому что приведение приводит к потере точности) val z: Long = y // Ошибка ``` + {% endtab %} {% endtabs %} @@ -349,7 +348,7 @@ val z: Long = y // Ошибка [reference]: {{ site.scala3ref }}/overview.html [matchable]: {{ site.scala3ref }}/other-new-features/matchable.html -[interpolation]: {% link _overviews/scala3-book/string-interpolation.md %} [fp]: {% link _overviews/scala3-book/fp-intro.md %} +[string-interpolation]: {% link _overviews/scala3-book/string-interpolation.md %} [option-api]: https://scala-lang.org/api/3.x/scala/Option.html [safe-null]: {{ site.scala3ref }}/experimental/explicit-nulls.html diff --git a/_ru/scala3/book/fp-functional-error-handling.md b/_ru/scala3/book/fp-functional-error-handling.md index bf6d299fbd..ca3f7857eb 100644 --- a/_ru/scala3/book/fp-functional-error-handling.md +++ b/_ru/scala3/book/fp-functional-error-handling.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе представлено введение в функциональную обработку ошибок в Scala 3. language: ru -num: 45 +num: 46 previous-page: fp-functions-are-values next-page: fp-summary --- diff --git a/_ru/scala3/book/fp-functions-are-values.md b/_ru/scala3/book/fp-functions-are-values.md index 62cacc4540..9a6cd6c423 100644 --- a/_ru/scala3/book/fp-functions-are-values.md +++ b/_ru/scala3/book/fp-functions-are-values.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе рассматривается использование функций в качестве значений в функциональном программировании. language: ru -num: 44 +num: 45 previous-page: fp-pure-functions next-page: fp-functional-error-handling --- diff --git a/_ru/scala3/book/fp-immutable-values.md b/_ru/scala3/book/fp-immutable-values.md index 24ffaf8613..53f63d0b26 100644 --- a/_ru/scala3/book/fp-immutable-values.md +++ b/_ru/scala3/book/fp-immutable-values.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе рассматривается использование неизменяемых значений в функциональном программировании. language: ru -num: 42 +num: 43 previous-page: fp-what-is-fp next-page: fp-pure-functions --- diff --git a/_ru/scala3/book/fp-intro.md b/_ru/scala3/book/fp-intro.md index 7961b13a83..a8a44521a2 100644 --- a/_ru/scala3/book/fp-intro.md +++ b/_ru/scala3/book/fp-intro.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: chapter description: В этой главе представлено введение в функциональное программирование в Scala 3. language: ru -num: 40 +num: 41 previous-page: collections-summary next-page: fp-what-is-fp --- diff --git a/_ru/scala3/book/fp-pure-functions.md b/_ru/scala3/book/fp-pure-functions.md index fd70cc5694..47a277a858 100644 --- a/_ru/scala3/book/fp-pure-functions.md +++ b/_ru/scala3/book/fp-pure-functions.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе рассматривается использование чистых функций в функциональном программировании. language: ru -num: 43 +num: 44 previous-page: fp-immutable-values next-page: fp-functions-are-values --- diff --git a/_ru/scala3/book/fp-summary.md b/_ru/scala3/book/fp-summary.md index 3a3cc5498d..0e18a20356 100644 --- a/_ru/scala3/book/fp-summary.md +++ b/_ru/scala3/book/fp-summary.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: Этот раздел суммирует предыдущие разделы функционального программирования. language: ru -num: 46 +num: 47 previous-page: fp-functional-error-handling next-page: types-introduction --- diff --git a/_ru/scala3/book/fp-what-is-fp.md b/_ru/scala3/book/fp-what-is-fp.md index 9e3f046542..8b624b5415 100644 --- a/_ru/scala3/book/fp-what-is-fp.md +++ b/_ru/scala3/book/fp-what-is-fp.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: Этот раздел дает ответ на вопрос, что такое функциональное программирование? language: ru -num: 41 +num: 42 previous-page: fp-intro next-page: fp-immutable-values --- diff --git a/_ru/scala3/book/fun-anonymous-functions.md b/_ru/scala3/book/fun-anonymous-functions.md index d5d0046917..98b7158e8f 100644 --- a/_ru/scala3/book/fun-anonymous-functions.md +++ b/_ru/scala3/book/fun-anonymous-functions.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице показано, как использовать анонимные функции в Scala, включая примеры с функциями map и filter класса List. language: ru -num: 28 +num: 29 previous-page: fun-intro next-page: fun-function-variables --- diff --git a/_ru/scala3/book/fun-eta-expansion.md b/_ru/scala3/book/fun-eta-expansion.md index 9e2baf3810..1cbbc3255a 100644 --- a/_ru/scala3/book/fun-eta-expansion.md +++ b/_ru/scala3/book/fun-eta-expansion.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице обсуждается Eta Expansion, технология Scala, которая автоматически и прозрачно преобразует методы в функции. language: ru -num: 30 +num: 31 previous-page: fun-function-variables next-page: fun-hofs --- diff --git a/_ru/scala3/book/fun-function-variables.md b/_ru/scala3/book/fun-function-variables.md index bd41113ac1..667d4e7c30 100644 --- a/_ru/scala3/book/fun-function-variables.md +++ b/_ru/scala3/book/fun-function-variables.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице показано, как использовать параметры функции в Scala. language: ru -num: 29 +num: 30 previous-page: fun-anonymous-functions next-page: fun-eta-expansion --- diff --git a/_ru/scala3/book/fun-hofs.md b/_ru/scala3/book/fun-hofs.md index ae8445463c..805f243533 100644 --- a/_ru/scala3/book/fun-hofs.md +++ b/_ru/scala3/book/fun-hofs.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице показано, как создавать и использовать функции высшего порядка в Scala. language: ru -num: 31 +num: 32 previous-page: fun-eta-expansion next-page: fun-write-map-function --- diff --git a/_ru/scala3/book/fun-intro.md b/_ru/scala3/book/fun-intro.md index e28840f949..01d2080096 100644 --- a/_ru/scala3/book/fun-intro.md +++ b/_ru/scala3/book/fun-intro.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: chapter description: В этой главе рассматриваются темы, связанные с функциями в Scala 3. language: ru -num: 27 +num: 28 previous-page: methods-summary next-page: fun-anonymous-functions --- diff --git a/_ru/scala3/book/fun-summary.md b/_ru/scala3/book/fun-summary.md index 77a72a05b2..20391f5af9 100644 --- a/_ru/scala3/book/fun-summary.md +++ b/_ru/scala3/book/fun-summary.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице представлен обзор предыдущего раздела 'Функции'. language: ru -num: 34 +num: 35 previous-page: fun-write-method-returns-function next-page: packaging-imports --- diff --git a/_ru/scala3/book/fun-write-map-function.md b/_ru/scala3/book/fun-write-map-function.md index 020a2e61a8..f7b6a0f63e 100644 --- a/_ru/scala3/book/fun-write-map-function.md +++ b/_ru/scala3/book/fun-write-map-function.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице описано, как создать свой собственный метод map language: ru -num: 32 +num: 33 previous-page: fun-hofs next-page: fun-write-method-returns-function --- diff --git a/_ru/scala3/book/fun-write-method-returns-function.md b/_ru/scala3/book/fun-write-method-returns-function.md index a322162e58..a2bb66c69c 100644 --- a/_ru/scala3/book/fun-write-method-returns-function.md +++ b/_ru/scala3/book/fun-write-method-returns-function.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице показано, как создавать методы, возвращающие функции, в Scala. language: ru -num: 33 +num: 34 previous-page: fun-write-map-function next-page: fun-summary --- diff --git a/_ru/scala3/book/methods-intro.md b/_ru/scala3/book/methods-intro.md index b5192db1cb..de34fc1166 100644 --- a/_ru/scala3/book/methods-intro.md +++ b/_ru/scala3/book/methods-intro.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: chapter description: В этой главе представлены методы в Scala 3. language: ru -num: 23 +num: 24 previous-page: domain-modeling-fp next-page: methods-most --- diff --git a/_ru/scala3/book/methods-main-methods.md b/_ru/scala3/book/methods-main-methods.md index 79fc169c54..46844f6485 100644 --- a/_ru/scala3/book/methods-main-methods.md +++ b/_ru/scala3/book/methods-main-methods.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: На этой странице описывается, как основные методы и аннотация @main работают в Scala 3. language: ru -num: 25 +num: 26 previous-page: methods-most next-page: methods-summary --- diff --git a/_ru/scala3/book/methods-most.md b/_ru/scala3/book/methods-most.md index 0554fa9464..b3d8f6ed81 100644 --- a/_ru/scala3/book/methods-most.md +++ b/_ru/scala3/book/methods-most.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе представлены методы Scala 3, включая main методы, методы расширения и многое другое. language: ru -num: 24 +num: 25 previous-page: methods-intro next-page: methods-main-methods --- diff --git a/_ru/scala3/book/methods-summary.md b/_ru/scala3/book/methods-summary.md index e19748a8fc..029c4de687 100644 --- a/_ru/scala3/book/methods-summary.md +++ b/_ru/scala3/book/methods-summary.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: Эта страница подводит итог предыдущим разделам о методах в Scala 3. language: ru -num: 26 +num: 27 previous-page: methods-main-methods next-page: fun-intro --- diff --git a/_ru/scala3/book/packaging-imports.md b/_ru/scala3/book/packaging-imports.md index bde9efdd30..89bee0a428 100644 --- a/_ru/scala3/book/packaging-imports.md +++ b/_ru/scala3/book/packaging-imports.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: chapter description: Обсуждение использования пакетов и импорта для организации кода, создания связанных модулей кода, управления областью действия и предотвращения конфликтов пространств имен. language: ru -num: 35 +num: 36 previous-page: fun-summary next-page: collections-intro --- diff --git a/_ru/scala3/book/string-interpolation.md b/_ru/scala3/book/string-interpolation.md new file mode 100644 index 0000000000..9e37b526fa --- /dev/null +++ b/_ru/scala3/book/string-interpolation.md @@ -0,0 +1,413 @@ +--- +layout: multipage-overview +title: Интерполяция строк +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: На этой странице представлена дополнительная информация о создании строк и использовании интерполяции строк. +language: ru +num: 18 +previous-page: first-look-at-types +next-page: control-structures +--- + +## Введение + +Интерполяция строк позволяет использовать внутри строк переменные. +Например: + +{% tabs example-1 %} +{% tab 'Scala 2 и 3' for=example-1 %} + +```scala +val name = "James" +val age = 30 +println(s"$name is $age years old") // "James is 30 years old" +``` + +{% endtab %} +{% endtabs %} + +Использование интерполяции строк заключается в том, что перед строковыми кавычками ставится символ `s`, +а перед любыми именами переменных ставится символ `$`. + +### Другие интерполяторы + +То `s`, что вы помещаете перед строкой, является лишь одним из возможных интерполяторов, предоставляемых Scala. + +Scala по умолчанию предоставляет три метода интерполяции строк: `s`, `f` и `raw`. +Кроме того, строковый интерполятор — это всего лишь специальный метод, и вы можете определить свой собственный. +Например, некоторые библиотеки баз данных определяют интерполятор `sql`, возвращающий запрос к базе данных. + +## Интерполятор `s` (`s`-строки) + +Добавление `s` перед любым строковым литералом позволяет использовать переменные непосредственно в строке. +Вы уже здесь видели пример: + +{% tabs example-2 %} +{% tab 'Scala 2 и 3' for=example-2 %} + +```scala +val name = "James" +val age = 30 +println(s"$name is $age years old") // "James is 30 years old" +``` + +{% endtab %} +{% endtabs %} + +Здесь переменные `$name` и `$age` заменяются в строке результатами вызова `name.toString` и `age.toString` соответственно. +`s`-строка будет иметь доступ ко всем переменным, в настоящее время находящимся в области видимости. + +Хотя это может показаться очевидным, важно здесь отметить, +что интерполяция строк _не_ будет выполняться в обычных строковых литералах: + +{% tabs example-3 %} +{% tab 'Scala 2 и 3' for=example-3 %} + +```scala +val name = "James" +val age = 30 +println("$name is $age years old") // "$name is $age years old" +``` + +{% endtab %} +{% endtabs %} + +Строковые интерполяторы также могут принимать произвольные выражения. +Например: + +{% tabs example-4 %} +{% tab 'Scala 2 и 3' for=example-4 %} + +```scala +println(s"2 + 2 = ${2 + 2}") // "2 + 2 = 4" +val x = -1 +println(s"x.abs = ${x.abs}") // "x.abs = 1" +``` + +{% endtab %} +{% endtabs %} + +Любое произвольное выражение может быть встроено в `${}`. + +Некоторые специальные символы необходимо экранировать при встраивании в строку. +Чтобы указать символ "знак доллара", вы можете удвоить его `$$`, как показано ниже: + +{% tabs example-5 %} +{% tab 'Scala 2 и 3' for=example-5 %} + +```scala +println(s"New offers starting at $$14.99") // "New offers starting at $14.99" +``` + +{% endtab %} +{% endtabs %} + +Двойные кавычки также необходимо экранировать. +Это можно сделать с помощью тройных кавычек, как показано ниже: + +{% tabs example-6 %} +{% tab 'Scala 2 и 3' for=example-6 %} + +```scala +println(s"""{"name":"James"}""") // `{"name":"James"}` +``` + +{% endtab %} +{% endtabs %} + +Наконец, все многострочные строковые литералы также могут быть интерполированы. + +{% tabs example-7 %} +{% tab 'Scala 2 и 3' for=example-7 %} + +```scala +println(s"""name: "$name", + |age: $age""".stripMargin) +``` + +Строка будет напечатана следующим образом: + +``` +name: "James" +age: 30 +``` + +{% endtab %} +{% endtabs %} + +## Интерполятор `f` (`f`-строки) + +Добавление `f` к любому строковому литералу позволяет создавать простые отформатированные строки, +аналогичные `printf` в других языках. +При использовании интерполятора `f` за всеми ссылками на переменные должна следовать строка формата в стиле `printf`, например `%d`. +Давайте посмотрим на пример: + +{% tabs example-8 %} +{% tab 'Scala 2 и 3' for=example-8 %} + +```scala +val height = 1.9d +val name = "James" +println(f"$name%s is $height%2.2f meters tall") // "James is 1.90 meters tall" +``` + +{% endtab %} +{% endtabs %} + +Интерполятор `f` типобезопасен. +Если вы попытаетесь передать в строку формата, который работает только для целых чисел, +значение `double`, компилятор выдаст ошибку. Например: + +{% tabs f-interpolator-error class=tabs-scala-version %} + +{% tab 'Scala 2' for=f-interpolator-error %} + +```scala +val height: Double = 1.9d + +scala> f"$height%4d" +:9: error: type mismatch; + found : Double + required: Int + f"$height%4d" + ^ +``` + +{% endtab %} + +{% tab 'Scala 3' for=f-interpolator-error %} + +```scala +val height: Double = 1.9d + +scala> f"$height%4d" +-- Error: ---------------------------------------------------------------------- +1 |f"$height%4d" + | ^^^^^^ + | Found: (height : Double), Required: Int, Long, Byte, Short, BigInt +1 error found + +``` + +{% endtab %} +{% endtabs %} + +Интерполятор `f` использует утилиты форматирования строк, доступные в Java. +Форматы, разрешенные после символа `%`, описаны в [Formatter javadoc][java-format-docs]. +Если после определения переменной нет символа `%`, предполагается форматирование `%s` (`String`). + +Наконец, как и в Java, используйте `%%` для получения буквенного символа `%` в итоговой строке: + +{% tabs literal-percent %} +{% tab 'Scala 2 и 3' for=literal-percent %} + +```scala +println(f"3/19 is less than 20%%") // "3/19 is less than 20%" +``` + +{% endtab %} +{% endtabs %} + +### Интерполятор `raw` + +Интерполятор `raw` похож на интерполятор `s`, +за исключением того, что он не выполняет экранирование литералов внутри строки. +Вот пример обработанной строки: + +{% tabs example-9 %} +{% tab 'Scala 2 и 3' for=example-9 %} + +```scala +scala> s"a\nb" +res0: String = +a +b +``` + +{% endtab %} +{% endtabs %} + +Здесь строковый интерполятор `s` заменил символы `\n` символом переноса строки. +Интерполятор `raw` этого не делает. + +{% tabs example-10 %} +{% tab 'Scala 2 и 3' for=example-10 %} + +```scala +scala> raw"a\nb" +res1: String = a\nb +``` + +{% endtab %} +{% endtabs %} + +Интерполятор `raw` полезен тогда, когда вы хотите избежать преобразования таких выражений, как `\n`, в символ переноса строки. + +В дополнение к трем строковым интерполяторам пользователи могут определить свои собственные. + +## Расширенное использование + +Литерал `s"Hi $name"` анализируется Scala как _обрабатываемый_ строковый литерал. +Это означает, что компилятор выполняет некоторую дополнительную работу с этим литералом. +Особенности обработанных строк и интерполяции строк описаны в [SIP-11][sip-11]. +Вот краткий пример, который поможет проиллюстрировать, как они работают. + +### Пользовательские интерполяторы + +В Scala все обрабатываемые строковые литералы представляют собой простые преобразования кода. +Каждый раз, когда компилятор встречает обрабатываемый строковый литерал вида: + +{% tabs example-11 %} +{% tab 'Scala 2 и 3' for=example-11 %} + +```scala +id"string content" +``` + +{% endtab %} +{% endtabs %} + +он преобразует его в вызов метода (`id`) для экземпляра [StringContext](https://www.scala-lang.org/api/current/scala/StringContext.html). +Этот метод также может быть доступен в неявной области видимости. +Чтобы определить собственную интерполяцию строк, нужно создать неявный класс (Scala 2) +или метод расширения (Scala 3), который добавляет новый метод для `StringContext`. + +В качестве простого примера предположим, что у нас есть простой класс `Point` +и мы хотим создать собственный интерполятор, который преобразует `p"a,b"` в объект `Point`. + +{% tabs custom-interpolator-1 %} +{% tab 'Scala 2 и 3' for=custom-interpolator-1 %} + +```scala +case class Point(x: Double, y: Double) + +val pt = p"1,-2" // Point(1.0,-2.0) +``` + +{% endtab %} +{% endtabs %} + +Мы бы создали собственный интерполятор `p`, +сначала внедрив расширение `StringContext`, например, так: + +{% tabs custom-interpolator-2 class=tabs-scala-version %} + +{% tab 'Scala 2' for=custom-interpolator-2 %} + +```scala +implicit class PointHelper(val sc: StringContext) extends AnyVal { + def p(args: Any*): Point = ??? +} +``` + +**Примечание**. Важно расширить `AnyVal` в Scala 2.x, +чтобы предотвратить создание экземпляра класса во время выполнения при каждой интерполяции. +Дополнительную информацию см. в документации по [value class]({% link _overviews/core/value-classes.md %}). + +{% endtab %} + +{% tab 'Scala 3' for=custom-interpolator-2 %} + +```scala +extension (sc: StringContext) + def p(args: Any*): Point = ??? +``` + +{% endtab %} + +{% endtabs %} + +Как только это расширение окажется в области видимости и компилятор Scala обнаружит `p"some string"`, +то превратит `some string` в токены String, а каждую встроенную переменную в аргументы выражения. + +Например, `p"1, $someVar"` превратится в: + +{% tabs extension-desugaring class=tabs-scala-version %} + +{% tab 'Scala 2' for=extension-desugaring %} + +```scala +new StringContext("1, ", "").p(someVar) +``` + +Затем неявный класс используется для перезаписи следующим образом: + +```scala +new PointHelper(new StringContext("1, ", "")).p(someVar) +``` + +{% endtab %} + +{% tab 'Scala 3' for=extension-desugaring %} + +```scala +StringContext("1, ", "").p(someVar) +``` + +{% endtab %} + +{% endtabs %} + +В результате каждый из фрагментов обработанной строки отображается в элементе `StringContext.parts`, +а любые значения выражений в строке передаются в параметр метода `args`. + +### Пример реализации + +Простая реализация метода интерполяции для нашего `Point` может выглядеть примерно так, как показано ниже, +хотя более детализированный метод может иметь более точный контроль +над обработкой строки `parts` и выражения `args` вместо повторного использования интерполятора `s`. + +{% tabs naive-implementation class=tabs-scala-version %} + +{% tab 'Scala 2' for=naive-implementation %} + +```scala +implicit class PointHelper(val sc: StringContext) extends AnyVal { + def p(args: Double*): Point = { + // переиспользование интерполятора `s` и затем разбиение по ',' + val pts = sc.s(args: _*).split(",", 2).map { _.toDoubleOption.getOrElse(0.0) } + Point(pts(0), pts(1)) + } +} + +val x=12.0 + +p"1, -2" // Point(1.0, -2.0) +p"${x/5}, $x" // Point(2.4, 12.0) +``` + +{% endtab %} + +{% tab 'Scala 3' for=naive-implementation %} + +```scala +extension (sc: StringContext) + def p(args: Double*): Point = { + // переиспользование интерполятора `s` и затем разбиение по ',' + val pts = sc.s(args: _*).split(",", 2).map { _.toDoubleOption.getOrElse(0.0) } + Point(pts(0), pts(1)) + } + +val x=12.0 + +p"1, -2" // Point(1.0, -2.0) +p"${x/5}, $x" // Point(2.4, 12.0) +``` + +{% endtab %} +{% endtabs %} + +Хотя строковые интерполяторы изначально использовались для создания нескольких строковых форм, +использование пользовательских интерполяторов, как указано выше, +может обеспечить более мощное синтаксическое сокращение, +и сообщество уже использует этот синтаксис для таких вещей, +как расширение цвета терминала ANSI, выполнение SQL-запросов, +магические представления `$"identifier"` и многие другие. + +[java-format-docs]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Formatter.html#detail + +[value-class]: {% link _overviews/core/value-classes.md %} +[sip-11]: {% link _sips/sips/string-interpolation.md %} diff --git a/_ru/scala3/book/types-generics.md b/_ru/scala3/book/types-generics.md index 653d6cacbd..5ece10b356 100644 --- a/_ru/scala3/book/types-generics.md +++ b/_ru/scala3/book/types-generics.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе представлены параметризованные типы в Scala 3. language: ru -num: 49 +num: 50 previous-page: types-inferred next-page: types-intersection --- diff --git a/_ru/scala3/book/types-inferred.md b/_ru/scala3/book/types-inferred.md index 70c44fcc9d..cadedc1ca0 100644 --- a/_ru/scala3/book/types-inferred.md +++ b/_ru/scala3/book/types-inferred.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе представлены и демонстрируются выводимые типы в Scala 3. language: ru -num: 48 +num: 49 previous-page: types-introduction next-page: types-generics --- diff --git a/_ru/scala3/book/types-intersection.md b/_ru/scala3/book/types-intersection.md index 6fa78e33ab..759855824b 100644 --- a/_ru/scala3/book/types-intersection.md +++ b/_ru/scala3/book/types-intersection.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе представлены пересечение типов в Scala 3. language: ru -num: 50 +num: 51 previous-page: types-generics next-page: types-union --- diff --git a/_ru/scala3/book/types-introduction.md b/_ru/scala3/book/types-introduction.md index 49b3cbfb49..65ecf50ebf 100644 --- a/_ru/scala3/book/types-introduction.md +++ b/_ru/scala3/book/types-introduction.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: chapter description: В этой главе представлено введение в типы и систему типов Scala 3. language: ru -num: 47 +num: 48 previous-page: fp-summary next-page: types-inferred --- diff --git a/_ru/scala3/book/types-union.md b/_ru/scala3/book/types-union.md index 35a0f440f6..6c28497626 100644 --- a/_ru/scala3/book/types-union.md +++ b/_ru/scala3/book/types-union.md @@ -7,7 +7,7 @@ overview-name: "Scala 3 — Book" type: section description: В этом разделе представлены объединение типов в Scala 3. language: ru -num: 51 +num: 52 previous-page: types-intersection next-page: ---