Skip to content

Tour packages actualization in ru #2886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 111 additions & 8 deletions _ru/tour/package-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,47 @@ language: ru
previous-page: packages-and-imports
---

# Объекты Пакета
Часто бывает удобно иметь определения, доступные для всего пакета,
когда не нужно придумывать имя для оболочки `object`, которая их содержит.

У каждого пакета может существовать связанный с этим пакетом объект (package object), общий для всех членов пакета. Такой объект может быть только один. Любые выражения, содержащиеся в объекте пакета, считаются членами самого пакета.
{% tabs pkg-obj-vs-top-lvl_1 class=tabs-scala-version %}
{% tab 'Scala 2' for=pkg-obj-vs-top-lvl_1 %}

Объекты пакета могут содержать произвольные виды выражений, а не только переменные и методы. Например, они часто используются для хранения псевдонимов типа и наборов неявных преобразований доступных всему пакету. Объекты пакета могут также наследоваться от классов и трейтов Scala.
Scala 2 предоставляет _объекты пакета_ (_package objects_) в виде удобного контейнера, общего для всего пакета.

Объекты пакета могут содержать произвольные виды выражений, а не только переменные и методы.
Например, они часто используются для хранения псевдонимов типа и наборов неявных преобразований доступных всему пакету.
Объекты пакета могут также наследоваться от классов и трейтов Scala.

> В будущей версии Scala 3 объекты пакета будут удалены в пользу определений верхнего уровня.

По соглашению, исходный код объекта пакета обычно помещается в файл под названием `package.scala`.

Каждому пакету разрешено иметь один объект пакета.
Любые выражения, содержащиеся в объекте пакета, считаются членами самого пакета.

{% endtab %}
{% tab 'Scala 3' for=pkg-obj-vs-top-lvl_1 %}

В Scala 3 любое определение может быть объявлено на верхнем уровне пакета.
Например, классы, перечисления, методы и переменные.

Любые определения, размещенные на верхнем уровне пакета, считаются членами самого пакета.

> В Scala 2 верхнеуровневый метод, определения типов и переменных должны были быть заключены в **объект пакета**.
> Их все еще можно использовать в Scala 3 для обратной совместимости.
> Вы можете увидеть, как они работают, переключая вкладки.

{% endtab %}
{% endtabs %}

См. пример ниже. Предположим, есть старший класс `Fruit` и три наследуемых от него объекта `Fruit` в пакете.

`gardening.fruits`:

{% tabs pkg-obj-vs-top-lvl_2 %}
{% tab 'Scala 2 и 3' for=pkg-obj-vs-top-lvl_2 %}

```
// в файле gardening/fruits/Fruit.scala
package gardening.fruits
Expand All @@ -29,9 +58,15 @@ object Plum extends Fruit("Plum", "blue")
object Banana extends Fruit("Banana", "yellow")
```

{% endtab %}
{% endtabs %}

Теперь предположим, что мы хотим поместить переменную `planted` и метод `showFruit` непосредственно в пакет `gardening`.
Вот как это делается:

{% tabs pkg-obj-vs-top-lvl_3 class=tabs-scala-version %}
{% tab 'Scala 2' for=pkg-obj-vs-top-lvl_3 %}

```
// в файле gardening/fruits/package.scala
package gardening
Expand All @@ -43,11 +78,31 @@ package object fruits {
}
```

Для примера, следующий объект `PrintPlanted` импортирует `planted` и `showFruit` точно так же, как с вариантом импорта класса `Fruit`, используя групповой стиль импорта пакета gardening.fruits:
{% endtab %}
{% tab 'Scala 3' for=pkg-obj-vs-top-lvl_3 %}

```
// в файле gardening/fruits/package.scala
package gardening.fruits

val planted = List(Apple, Plum, Banana)
def showFruit(fruit: Fruit): Unit =
println(s"${fruit.name}s are ${fruit.color}")
```

{% endtab %}
{% endtabs %}

Для примера, следующий объект `PrintPlanted` импортирует `planted` и `showFruit` точно так же, как с вариантом импорта класса `Fruit`,
используя групповой стиль импорта пакета `gardening.fruits`:

{% tabs pkg-obj-vs-top-lvl_4 class=tabs-scala-version %}
{% tab 'Scala 2' for=pkg-obj-vs-top-lvl_4 %}

```
// в файле PrintPlanted.scala
import gardening.fruits._

object PrintPlanted {
def main(args: Array[String]): Unit = {
for (fruit <- planted) {
Expand All @@ -57,10 +112,58 @@ object PrintPlanted {
}
```

Объекты пакета ведут себя также, как и любые другие объекты. Это означает, что вы можете использовать наследование, при этом сразу нескольких трейтов:
{% endtab %}
{% tab 'Scala 3' for=pkg-obj-vs-top-lvl_4 %}

```
package object fruits extends FruitAliases with FruitHelpers {
// здесь располагаются вспомогательные классы и переменные
}
// в файле PrintPlanted.scala
import gardening.fruits.*

@main def printPlanted(): Unit =
for fruit <- planted do
showFruit(fruit)
```

{% endtab %}
{% endtabs %}

### Объединение нескольких определений на уровне пакета

Часто в вашем проекте может быть несколько повторно используемых определений,
заданных в различных модулях, которые вы хотите агрегировать на верхнем уровне пакета.

Например, некоторые вспомогательные методы в трейте `FruitHelpers`
и некоторые псевдонимы терминов/типов в свойстве `FruitAliases`.
Вот как вы можете разместить все их определения на уровне пакета `fruit`:

{% tabs pkg-obj-vs-top-lvl_5 class=tabs-scala-version %}
{% tab 'Scala 2' for=pkg-obj-vs-top-lvl_5 %}

Объекты пакета ведут себя также, как и любые другие объекты.
Это означает, что вы можете использовать наследование, при этом сразу нескольких трейтов:

```
package gardening

// `fruits` наследует свои элементы от родителей.
package object fruits extends FruitAliases with FruitHelpers
```

{% endtab %}
{% tab 'Scala 3' for=pkg-obj-vs-top-lvl_5 %}

В Scala 3 предпочтительно использовать `export` для объединения членов из нескольких объектов в единую область видимости.
Здесь мы определяем приватные объекты, которые смешиваются с вспомогательными трейтами,
а затем экспортируют их элементы на верхнем уровне:

```
package gardening.fruits

private object FruitAliases extends FruitAliases
private object FruitHelpers extends FruitHelpers

export FruitHelpers.*, FruitAliases.*
```

{% endtab %}
{% endtabs %}
101 changes: 96 additions & 5 deletions _ru/tour/packages-and-imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,28 @@ previous-page: annotations
next-page: package-objects
---

# Пакеты и Импорт
# Пакеты и Импорт

Scala использует пакеты для указания пространства имен, они позволяют создавать модульную структуру кода.

## Создание пакета

Пакеты создаются путем объявления одного или нескольких имен пакетов в верхней части файла Scala.

{% tabs packages-and-imports_1 %}
{% tab 'Scala 2 и 3' for=packages-and-imports_1 %}

```
package users

class User
```

{% endtab %}
{% endtabs %}

По соглашению пакеты называют тем же именем, что и каталог, содержащий файл Scala. Однако Scala не обращает внимания на расположение файлов. Структура каталогов sbt-проекта для `package users` может выглядеть следующим образом:

```
- ExampleProject
- build.sbt
Expand All @@ -33,8 +43,15 @@ class User
UserPreferences.scala
- test
```
Обратите внимание, что каталог `users` находится внутри каталога `scala` и как в пакете содержатся несколько файлов Scala. Каждый файл Scala в пакете может иметь одно и то же объявление пакета. Другой способ объявления пакетов - с помощью фигурных скобок:
```

Обратите внимание, что каталог `users` находится внутри каталога `scala` и как в пакете содержатся несколько файлов Scala.
Каждый файл Scala в пакете может иметь одно и то же объявление пакета.
Другой способ объявления пакетов - вложить их друг в друга::

{% tabs packages-and-imports_2 class=tabs-scala-version %}
{% tab 'Scala 2' for=packages-and-imports_2 %}

```scala
package users {
package administrators {
class NormalUser
Expand All @@ -44,39 +61,113 @@ package users {
}
}
```

{% endtab %}
{% tab 'Scala 3' for=packages-and-imports_2 %}

```scala
package users:
package administrators:
class NormalUser

package normalusers:
class NormalUser
```

{% endtab %}
{% endtabs %}

Как видите, такой способ позволяет вкладывать пакеты друг в друга, а также обеспечивает отличный контроль за областью видимости и возможностью изоляции.

Имя пакета должно быть все в нижнем регистре, и если код разрабатывается в организации имеющей сайт, то следует использовать имя следующего формата: `<домен-верхнего-уровня>.<доменное-имя>.<название-проекта>`. Например, если бы у Google был проект под названием `SelfDrivingCar`, название пакета выглядело бы следующим образом:
```

{% tabs packages-and-imports_3 %}
{% tab 'Scala 2 и 3' for=packages-and-imports_3 %}

```scala
package com.google.selfdrivingcar.camera

class Lens
```

{% endtab %}
{% endtabs %}

Что может соответствовать следующей структуре каталога: `SelfDrivingCar/src/main/scala/com/google/selfdrivingcar/camera/Lens.scala`.

## Импорт

Указание `import` открывает доступ к членам (классам, трейтам, функциям и т.д.) в других пакетах. Указание `import` не требуется для доступа к членам одного и того же пакета. Указание `import` избирательны:

{% tabs packages-and-imports_4 class=tabs-scala-version %}
{% tab 'Scala 2' for=packages-and-imports_4 %}

```
import users._ // групповой импорт всего пакета users
import users.User // импортировать только User
import users.{User, UserPreferences} // импортировать только User, UserPreferences
import users.{UserPreferences => UPrefs} // импортировать и переименовать
```

{% endtab %}
{% tab 'Scala 3' for=packages-and-imports_4 %}

```
import users.* // групповой импорт всего пакета users, кроме given
import users.given // импорт всех given пакета users
import users.User // импортировать только User
import users.{User, UserPreferences} // импортировать только User, UserPreferences
import users.UserPreferences as UPrefs // импортировать и переименовать
```

{% endtab %}
{% endtabs %}

Одним из отличий Scala от Java является то, что импорт можно использовать где угодно:

{% tabs packages-and-imports_5 class=tabs-scala-version %}
{% tab 'Scala 2' for=packages-and-imports_5 %}

```scala mdoc
def sqrtplus1(x: Int) = {
import scala.math.sqrt
sqrt(x) + 1.0
}
```
В случае возникновения конфликта имен и необходимости импортировать что-либо из корня проекта, имя пакета должно начинаться с префикса `_root_`:

{% endtab %}
{% tab 'Scala 3' for=packages-and-imports_5 %}

```scala
def sqrtplus1(x: Int) =
import scala.math.sqrt
sqrt(x) + 1.0
```

{% endtab %}
{% endtabs %}

В случае возникновения конфликта имен и необходимости импортировать что-либо из корня проекта, имя пакета должно начинаться с префикса `_root_`:

{% tabs packages-and-imports_6 class=tabs-scala-version %}
{% tab 'Scala 2' for=packages-and-imports_6 %}

```scala
package accounts

import _root_.users._
```

{% endtab %}
{% tab 'Scala 3' for=packages-and-imports_6 %}

```scala
package accounts

import _root_.users.*
```

{% endtab %}
{% endtabs %}

Примечание: Пакеты `scala` и `java.lang`, а также `object Predef` импортируются по умолчанию.
2 changes: 1 addition & 1 deletion _ru/tour/pattern-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ x match
{% endtab %}
{% endtabs %}

Значение константы `x` выше представляет собой случайное целое число от 0 до 10. `x` становится левым операндом оператора `match`, а справа - выражением с четырьмя примерами (называемые еще _вариантами_). Последний вариант `_` - позволяет "поймать все оставшиеся варианты" т. е. для любого числа больше 2.
Значение константы `x` выше представляет собой случайное целое число от 0 до 9. `x` становится левым операндом оператора `match`, а справа - выражением с четырьмя примерами (называемые еще _вариантами_). Последний вариант `_` - позволяет "поймать все оставшиеся варианты" т. е. для любого числа больше 2.

Сопоставление с примером возвращает значение.

Expand Down