diff --git a/_overviews/scala3-book/packaging-imports.md b/_overviews/scala3-book/packaging-imports.md index 94126b7f3..4c5857cc5 100644 --- a/_overviews/scala3-book/packaging-imports.md +++ b/_overviews/scala3-book/packaging-imports.md @@ -47,10 +47,11 @@ The syntax shown above applies to the entire source file: all the definitions in at the beginning of the file. Alternatively, it is possible to write package clauses that apply only to the definitions -they contain: +they contain: -{% tabs packaging-imports-1 class=tabs-scala-version %} -{% tab 'Scala 2' %}```scala +{% tabs packaging-imports-0 class=tabs-scala-version %} +{% tab 'Scala 2' %} +```scala package users { package administrators { // the full name of this package is users.administrators @@ -63,7 +64,7 @@ package users { ``` {% endtab %} -{% tab 'Scala 3' for=packaging-imports-1 %} +{% tab 'Scala 3' %} ```scala package users: @@ -462,7 +463,7 @@ The basic form is shown in this example: ```scala object A: class TC - given tc as TC + given tc: TC def f(using TC) = ??? object B: @@ -527,10 +528,10 @@ For example, when you have this `object`: {% tab 'Scala 3 only' %} ```scala object Instances: - given intOrd as Ordering[Int] - given listOrd[T: Ordering] as Ordering[List[T]] - given ec as ExecutionContext = ... - given im as Monoid[Int] + given intOrd: Ordering[Int] + given listOrd[T: Ordering]: Ordering[List[T]] + given ec: ExecutionContext = ... + given im: Monoid[Int] ``` {% endtab %} {% endtabs %} @@ -570,14 +571,14 @@ object MonthConversions: def convert(a: A): String given intMonthConverter: MonthConverter[Int] with - def convert(i: Int): String = + def convert(i: Int): String = i match case 1 => "January" case 2 => "February" // more cases here ... given stringMonthConverter: MonthConverter[String] with - def convert(s: String): String = + def convert(s: String): String = s match case "jan" => "January" case "feb" => "February" diff --git a/_ru/scala3/book/packaging-imports.md b/_ru/scala3/book/packaging-imports.md index 89bee0a42..49b5da759 100644 --- a/_ru/scala3/book/packaging-imports.md +++ b/_ru/scala3/book/packaging-imports.md @@ -13,11 +13,11 @@ next-page: collections-intro --- -Scala использует _packages_ для создания пространств имен, которые позволяют модульно разбивать программы. -Scala поддерживает стиль именования пакетов, используемый в Java, а также нотацию пространства имен “фигурные скобки”, +Scala использует _packages_ для создания пространств имен, которые позволяют модульно разбивать программы. +Scala поддерживает стиль именования пакетов, используемый в Java, а также нотацию пространства имен “фигурные скобки”, используемую такими языками, как C++ и C#. -Подход Scala к импорту похож на Java, но более гибкий. +Подход Scala к импорту похож на Java, но более гибкий. С помощью Scala можно: - импортировать пакеты, классы, объекты, trait-ы и методы @@ -29,8 +29,8 @@ Scala поддерживает стиль именования пакетов, ## Создание пакета -Пакеты создаются путем объявления одного или нескольких имен пакетов в начале файла Scala. -Например, если ваше доменное имя _acme.com_ и вы работаете с пакетом _model_ приложения с именем _myapp_, +Пакеты создаются путем объявления одного или нескольких имен пакетов в начале файла Scala. +Например, если ваше доменное имя _acme.com_ и вы работаете с пакетом _model_ приложения с именем _myapp_, объявление пакета выглядит следующим образом: ```scala @@ -39,18 +39,18 @@ package com.acme.myapp.model class Person ... ``` -По соглашению все имена пакетов должны быть строчными, +По соглашению все имена пакетов должны быть строчными, а формальным соглашением об именах является _\.\.\.\_. -Хотя это и не обязательно, имена пакетов обычно совпадают с именами иерархии каталогов. -Поэтому, если следовать этому соглашению, класс `Person` в этом проекте будет найден +Хотя это и не обязательно, имена пакетов обычно совпадают с именами иерархии каталогов. +Поэтому, если следовать этому соглашению, класс `Person` в этом проекте будет найден в файле _MyApp/src/main/scala/com/acme/myapp/model/Person.scala_. ### Использование нескольких пакетов в одном файле -Показанный выше синтаксис применяется ко всему исходному файлу: -все определения в файле `Person.scala` принадлежат пакету `com.acme.myapp.model` +Показанный выше синтаксис применяется ко всему исходному файлу: +все определения в файле `Person.scala` принадлежат пакету `com.acme.myapp.model` в соответствии с предложением `package` в начале файла. В качестве альтернативы можно написать `package`, которые применяются только к содержащимся в них определениям: @@ -67,20 +67,20 @@ package users: Обратите внимание, что за именами пакетов следует двоеточие, а определения внутри пакета имеют отступ. -Преимущество этого подхода заключается в том, что он допускает вложение пакетов +Преимущество этого подхода заключается в том, что он допускает вложение пакетов и обеспечивает более очевидный контроль над областью видимости и инкапсуляцией, особенно в пределах одного файла. ## Операторы импорта -Операторы импорта используются для доступа к сущностям в других пакетах. +Операторы импорта используются для доступа к сущностям в других пакетах. Операторы импорта делятся на две основные категории: - импорт классов, трейтов, объектов, функций и методов - импорт `given` предложений -Первая категория операторов импорта аналогична тому, что использует Java, -с немного другим синтаксисом, обеспечивающим большую гибкость. +Первая категория операторов импорта аналогична тому, что использует Java, +с немного другим синтаксисом, обеспечивающим большую гибкость. Пример: ```` @@ -90,10 +90,10 @@ import users.{User, UserPreferences} // импортируются толь import users.{UserPreferences as UPrefs} // переименование импортированного члена ```` -Эти примеры предназначены для того, чтобы дать представление о том, как работает первая категория операторов `import`. +Эти примеры предназначены для того, чтобы дать представление о том, как работает первая категория операторов `import`. Более подробно они объясняются в следующих подразделах. -Операторы импорта также используются для импорта `given` экземпляров в область видимости. +Операторы импорта также используются для импорта `given` экземпляров в область видимости. Они обсуждаются в конце этой главы. > import не требуется для доступа к членам одного и того же пакета. @@ -130,15 +130,15 @@ import scala.concurrent.* ### Переименование элементов при импорте -Иногда необходимо переименовать объекты при их импорте, чтобы избежать конфликтов имен. -Например, если нужно использовать Scala класс `List` вместе с `java.util.List`, +Иногда необходимо переименовать объекты при их импорте, чтобы избежать конфликтов имен. +Например, если нужно использовать Scala класс `List` вместе с `java.util.List`, то можно переименовать `java.util.List` при импорте: ```scala import java.util.{List as JavaList} ``` -Теперь имя `JavaList` можно использовать для ссылки на класс `java.util.List` +Теперь имя `JavaList` можно использовать для ссылки на класс `java.util.List` и использовать `List` для ссылки на Scala класс `List`. Также можно переименовывать несколько элементов одновременно, используя следующий синтаксис: @@ -147,21 +147,21 @@ import java.util.{List as JavaList} import java.util.{Date as JDate, HashMap as JHashMap, *} ``` -В этой строке кода говорится следующее: “Переименуйте классы `Date` и `HashMap`, как показано, +В этой строке кода говорится следующее: “Переименуйте классы `Date` и `HashMap`, как показано, и импортируйте все остальное из пакета `java.util`, не переименовывая”. ### Скрытие членов при импорте -При импорте часть объектов можно _скрывать_. -Следующий оператор импорта скрывает класс `java.util.Random`, +При импорте часть объектов можно _скрывать_. +Следующий оператор импорта скрывает класс `java.util.Random`, в то время как все остальное в пакете `java.util` импортируется: ```scala import java.util.{Random as _, *} ``` -Если попытаться получить доступ к классу `Random`, то выдается ошибка, +Если попытаться получить доступ к классу `Random`, то выдается ошибка, но есть доступ ко всем остальным членам пакета `java.util`: ```scala @@ -200,7 +200,7 @@ val c: Map[Int, Int] = Map(1 -> 1, 2 -> 2) ### Импорт можно использовать в любом месте -В Scala операторы `import` могут быть объявлены где угодно. +В Scala операторы `import` могут быть объявлены где угодно. Их можно использовать в верхней части файла исходного кода: ```scala @@ -233,8 +233,8 @@ class ClassB: ### “Статический” импорт -Если необходимо импортировать элементы способом, аналогичным подходу “статического импорта” в Java, -то есть для того, чтобы напрямую обращаться к членам класса, не добавляя к ним префикс с именем класса, +Если необходимо импортировать элементы способом, аналогичным подходу “статического импорта” в Java, +то есть для того, чтобы напрямую обращаться к членам класса, не добавляя к ним префикс с именем класса, используется следующий подход. Синтаксис для импорта всех статических членов Java класса `Math`: @@ -243,7 +243,7 @@ class ClassB: import java.lang.Math.* ``` -Теперь можно получить доступ к статическим методам класса `Math`, +Теперь можно получить доступ к статическим методам класса `Math`, таким как `sin` и `cos`, без необходимости предварять их именем класса: ```scala @@ -263,13 +263,13 @@ val b = cos(PI) // -1.0 Члены object `Predef` также импортируются по умолчанию. -> Например, такие классы, как `List`, `Vector`, `Map` и т.д. можно использовать явно, не импортируя их - +> Например, такие классы, как `List`, `Vector`, `Map` и т.д. можно использовать явно, не импортируя их - > они доступны, потому что определены в object `Predef` ### Обработка конфликтов имен -Если необходимо импортировать что-то из корня проекта и возникает конфликт имен, +Если необходимо импортировать что-то из корня проекта и возникает конфликт имен, достаточно просто добавить к имени пакета префикс `_root_`: ``` @@ -281,14 +281,14 @@ import _root_.accounts.* ## Импорт экземпляров `given` -Как будет показано в главе [“Контекстные абстракции”][contextual], -для импорта экземпляров `given` используется специальная форма оператора `import`. +Как будет показано в главе [“Контекстные абстракции”][contextual], +для импорта экземпляров `given` используется специальная форма оператора `import`. Базовая форма показана в этом примере: ```scala object A: class TC - given tc as TC + given tc: TC def f(using TC) = ??? object B: @@ -296,8 +296,8 @@ object B: import A.given // импорт экземпляров given ``` -В этом коде предложение `import A.*` объекта `B` импортирует все элементы `A`, _кроме_ `given` экземпляра `tc`. -И наоборот, второй импорт, `import A.given`, импортирует _только_ `given` экземпляр. +В этом коде предложение `import A.*` объекта `B` импортирует все элементы `A`, _кроме_ `given` экземпляра `tc`. +И наоборот, второй импорт, `import A.given`, импортирует _только_ `given` экземпляр. Два предложения импорта также могут быть объединены в одно: ```scala @@ -307,23 +307,23 @@ object B: ### Обсуждение -Селектор с подстановочным знаком `*` помещает в область видимости все определения, кроме `given`, +Селектор с подстановочным знаком `*` помещает в область видимости все определения, кроме `given`, тогда как селектор выше помещает в область действия все данные, включая те, которые являются результатом расширений. Эти правила имеют два основных преимущества: -- более понятно, откуда берутся данные given. +- более понятно, откуда берутся данные given. В частности, невозможно скрыть импортированные given в длинном списке других импортируемых подстановочных знаков. -- есть возможность импортировать все given, не импортируя ничего другого. +- есть возможность импортировать все given, не импортируя ничего другого. Это особенно важно, поскольку given могут быть анонимными, поэтому обычное использование именованного импорта нецелесообразно. ### Импорт по типу -Поскольку given-ы могут быть анонимными, не всегда практично импортировать их по имени, -и вместо этого обычно используется импорт подстановочных знаков. -_Импорт по типу_ предоставляет собой более конкретную альтернативу импорту с подстановочными знаками, -делая понятным то, что импортируется. +Поскольку given-ы могут быть анонимными, не всегда практично импортировать их по имени, +и вместо этого обычно используется импорт подстановочных знаков. +_Импорт по типу_ предоставляет собой более конкретную альтернативу импорту с подстановочными знаками, +делая понятным то, что импортируется. ```scala import A.{given TC} @@ -336,26 +336,26 @@ import A.{given TC} import A.{given T1, ..., given Tn} ``` -Импорт всех `given` экземпляров параметризованного типа достигается аргументами с подстановочными знаками. +Импорт всех `given` экземпляров параметризованного типа достигается аргументами с подстановочными знаками. Например, есть такой `объект`: ```scala object Instances: - given intOrd as Ordering[Int] - given listOrd[T: Ordering] as Ordering[List[T]] - given ec as ExecutionContext = ... - given im as Monoid[Int] + given intOrd: Ordering[Int] + given listOrd[T: Ordering]: Ordering[List[T]] + given ec: ExecutionContext = ... + given im: Monoid[Int] ``` -Оператор `import` ниже импортирует экземпляры `intOrd`, `listOrd` и `ec`, но пропускает экземпляр `im`, +Оператор `import` ниже импортирует экземпляры `intOrd`, `listOrd` и `ec`, но пропускает экземпляр `im`, поскольку он не соответствует ни одному из указанных шаблонов: ```scala import Instances.{given Ordering[?], given ExecutionContext} ``` -Импорт по типу можно смешивать с импортом по имени. -Если оба присутствуют в предложении import, импорт по типу идет последним. +Импорт по типу можно смешивать с импортом по имени. +Если оба присутствуют в предложении import, импорт по типу идет последним. Например, это предложение импорта импортирует `im`, `intOrd` и `listOrd`, но не включает `ec`: ```scala @@ -365,7 +365,7 @@ import Instances.{im, given Ordering[?]} ### Пример -В качестве конкретного примера представим, что у нас есть объект `MonthConversions`, +В качестве конкретного примера представим, что у нас есть объект `MonthConversions`, который содержит два определения `given`: ```scala @@ -374,14 +374,14 @@ object MonthConversions: def convert(a: A): String given intMonthConverter: MonthConverter[Int] with - def convert(i: Int): String = + def convert(i: Int): String = i match case 1 => "January" case 2 => "February" // остальные случаи здесь ... given stringMonthConverter: MonthConverter[String] with - def convert(s: String): String = + def convert(s: String): String = s match case "jan" => "January" case "feb" => "February" @@ -410,8 +410,8 @@ def genericMonthConverter[A](a: A)(using monthConverter: MonthConverter[A]): Str println(genericMonthConverter("jan")) // January ``` -Как уже упоминалось ранее, одно из ключевых преимуществ синтаксиса “import given” состоит в том, -чтобы прояснить, откуда берутся данные в области действия, +Как уже упоминалось ранее, одно из ключевых преимуществ синтаксиса “import given” состоит в том, +чтобы прояснить, откуда берутся данные в области действия, и в `import` операторах выше ясно, что данные поступают из объекта `MonthConversions`. diff --git a/_zh-cn/overviews/scala3-book/packaging-imports.md b/_zh-cn/overviews/scala3-book/packaging-imports.md index 4ef39fbf1..b85798e93 100644 --- a/_zh-cn/overviews/scala3-book/packaging-imports.md +++ b/_zh-cn/overviews/scala3-book/packaging-imports.md @@ -31,7 +31,7 @@ Scala 导入成员的方法也类似于 Java,并且更灵活。 通过在 Scala 文件的顶部声明一个或多个包名称来创建包。 例如,当您的域名是 _acme.com_ 并且您正在使用名为 _myapp_ 的应用程序中的 _model_ 包中工作时,您的包声明如下所示: -{% tabs packaging-imports-1 %} +{% tabs packaging-imports-0 %} {% tab 'Scala 2 and 3' %} ```scala package com.acme.myapp.model @@ -466,7 +466,7 @@ import _root_.accounts.* ```scala object A: class TC - given tc as TC + given tc: TC def f(using TC) = ??? object B: @@ -531,10 +531,10 @@ import A.{given T1, ..., given Tn} {% tab 'Scala 3 only' %} ```scala object Instances: - given intOrd as Ordering[Int] - given listOrd[T: Ordering] as Ordering[List[T]] - given ec as ExecutionContext = ... - given im as Monoid[Int] + given intOrd: Ordering[Int] + given listOrd[T: Ordering]: Ordering[List[T]] + given ec: ExecutionContext = ... + given im: Monoid[Int] ``` {% endtab %} {% endtabs %} @@ -574,14 +574,14 @@ object MonthConversions: def convert(a: A): String given intMonthConverter: MonthConverter[Int] with - def convert(i: Int): String = + def convert(i: Int): String = i match case 1 => "January" case 2 => "February" // more cases here ... given stringMonthConverter: MonthConverter[String] with - def convert(s: String): String = + def convert(s: String): String = s match case "jan" => "January" case "feb" => "February"