Skip to content

Commit 80a950c

Browse files
artemkorsakovjulienrf
authored andcommitted
Update singleton-objects.md in russian
1 parent f5f8e74 commit 80a950c

File tree

2 files changed

+134
-8
lines changed

2 files changed

+134
-8
lines changed

_ru/tour/singleton-objects.md

Lines changed: 133 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,67 @@ next-page: regular-expression-patterns
88
previous-page: pattern-matching
99
prerequisite-knowledge: classes, methods, private-methods, packages, option
1010
---
11+
1112
Все объекты являются одиночками (Singleton Object) - то есть существуют в единственном экземпляре. Он создается лениво, когда на него ссылаются, также как ленивые значения (lazy val).
1213

1314
На самом верхнем уровне объект является одиночкой.
1415

1516
Как член класса или как локальная переменная, он ведет себя точно так же как ленивое значение (lazy val).
17+
1618
# Объявление одиночного объекта
19+
1720
Объект - является значением. Объявление объекта происходит схожим с классом образом, но используется ключевое слово `object`:
21+
22+
{% tabs object-definition-box %}
23+
24+
{% tab 'Scala 2 и 3' for=object-definition-box %}
25+
1826
```scala mdoc
1927
object Box
2028
```
2129

30+
{% endtab %}
31+
32+
{% endtabs %}
33+
2234
Вот пример объекта с методом:
23-
```
35+
36+
{% tabs singleton-logger-example class=tabs-scala-version %}
37+
38+
{% tab 'Scala 2' for=singleton-logger-example %}
39+
40+
```scala
2441
package logging
2542

2643
object Logger {
2744
def info(message: String): Unit = println(s"INFO: $message")
2845
}
2946
```
47+
48+
{% endtab %}
49+
50+
{% tab 'Scala 3' for=singleton-logger-example %}
51+
52+
```scala
53+
package logging
54+
55+
object Logger:
56+
def info(message: String): Unit = println(s"INFO: $message")
57+
```
58+
59+
{% endtab %}
60+
61+
{% endtabs %}
62+
3063
Метод `info` может быть импортирован в любом месте программы. Создание подобных методов является распространенным вариантом использования одиночных объектов.
3164

3265
Давайте посмотрим, как использовать `info` в другом пакете:
3366

34-
```
67+
{% tabs singleton-usage-example class=tabs-scala-version %}
68+
69+
{% tab 'Scala 2' for=singleton-usage-example %}
70+
71+
```scala
3572
import logging.Logger.info
3673

3774
class Project(name: String, daysToComplete: Int)
@@ -43,15 +80,44 @@ class Test {
4380
}
4481
```
4582

83+
{% endtab %}
84+
85+
{% tab 'Scala 3' for=singleton-usage-example %}
86+
87+
```scala
88+
import logging.Logger.info
89+
90+
class Project(name: String, daysToComplete: Int)
91+
92+
class Test:
93+
val project1 = Project("TPS Reports", 1)
94+
val project2 = Project("Website redesign", 5)
95+
info("Created projects") // Prints "INFO: Created projects"
96+
```
97+
98+
{% endtab %}
99+
100+
{% endtabs %}
101+
46102
Метод `info` виден благодаря указанию импорта `import logging.Logger.info`.
103+
Для импорта требуется "постоянный путь" к импортируемому символу, а путь к объекту неизменен.
47104

48-
Замечание: Если `object` не является объектом верхнего уровня, но вложен в другой класс или объект, то объект, как и любой другой член, "зависим от пути".
105+
Замечание: Если `object` не является объектом верхнего уровня, но вложен в другой класс или объект,
106+
то объект, как и любой другой член, "зависим от пути".
107+
Это означает, что для двух видов напитков, `class Milk` и `class OrangeJuice`,
108+
элемент класса `object NutritionInfo` "зависит" от включающего его экземпляра, будь то `Milk` или `OrangeJuice`.
109+
`milk.NutritionInfo` полностью отличается от `oj.NutritionInfo`.
49110

50111
## Объекты компаньоны
51112

52113
Объект с тем же именем, что и класс называется _объект компаньон_ (companion object). И наоборот, класс является классом-компаньоном объекта. Класс или объект компаньон может получить доступ к приватным членам своего спутника. Используйте объект компаньон для методов и значений, которые не специфичны для экземпляров класса компаньона.
53-
```
54-
import scala.math._
114+
115+
{% tabs companion-object-circle class=tabs-scala-version %}
116+
117+
{% tab 'Scala 2' for=companion-object-circle %}
118+
119+
```scala
120+
import scala.math.pow
55121

56122
case class Circle(radius: Double) {
57123
import Circle._
@@ -67,9 +133,37 @@ val circle1 = Circle(5.0)
67133
circle1.area
68134
```
69135

136+
{% endtab %}
137+
138+
{% tab 'Scala 3' for=companion-object-circle %}
139+
140+
```scala
141+
import scala.math.pow
142+
143+
case class Circle(radius: Double):
144+
import Circle.*
145+
def area: Double = calculateArea(radius)
146+
147+
object Circle:
148+
private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0)
149+
150+
151+
val circle1 = Circle(5.0)
152+
153+
circle1.area
154+
```
155+
156+
{% endtab %}
157+
158+
{% endtabs %}
159+
70160
Класс `Circle` имеет член `area`, который специфичен для каждого конкретного экземпляра, а метод `calculateArea` одиночного объекта `Circle`, доступен для каждого экземпляра класса `Circle`.
71161

72162
Объект компаньон может также содержать методы создающие конкретные экземпляры класса спутника:
163+
{% tabs companion-object-email class=tabs-scala-version %}
164+
165+
{% tab 'Scala 2' for=companion-object-email %}
166+
73167
```scala mdoc
74168
class Email(val username: String, val domainName: String)
75169

@@ -88,16 +182,48 @@ scalaCenterEmail match {
88182
s"""Registered an email
89183
|Username: ${email.username}
90184
|Domain name: ${email.domainName}
91-
""")
185+
""".stripMargin)
92186
case None => println("Error: could not parse email")
93187
}
94188
```
189+
190+
{% endtab %}
191+
192+
{% tab 'Scala 3' for=companion-object-email %}
193+
194+
```scala
195+
class Email(val username: String, val domainName: String)
196+
197+
object Email:
198+
def fromString(emailString: String): Option[Email] =
199+
emailString.split('@') match
200+
case Array(a, b) => Some(Email(a, b))
201+
case _ => None
202+
203+
val scalaCenterEmail = Email.fromString("[email protected]")
204+
scalaCenterEmail match
205+
case Some(email) => println(
206+
s"""Registered an email
207+
|Username: ${email.username}
208+
|Domain name: ${email.domainName}
209+
""".stripMargin)
210+
case None => println("Error: could not parse email")
211+
```
212+
213+
{% endtab %}
214+
215+
{% endtabs %}
216+
95217
`object Email` содержит производящий метод `fromString`, который создает экземпляр `Email` из строки. Мы возвращаем результат как `Option[Email]` на случай возникновения ошибок парсинга.
96218

97219
Примечание: Если у класса или объекта есть компаньон, они должны быть размещены в одном и том же файле. Чтобы задать компаньонов в REPL, либо определите их на той же строке, либо перейдите в режим `:paste`.
98220

99-
## Примечания для Java-программистов ##
221+
## Примечания для Java-программистов
100222

101223
`static` члены в Java смоделированы как обычные члены объекта компаньона в Scala.
102224

103225
При использовании объекта компаньона из Java-кода, члены будут определены в сопутствующем классе компаньоне с `static` модификатором. Это называется _пробрасывание статики_. Такое происходит, даже если вы сами не определили класс компаньон.
226+
227+
## Дополнительные ресурсы
228+
229+
- Узнайте больше об объектах компаньонах в [Scala Book](/scala3/book/domain-modeling-tools.html#companion-objects)

_tour/singleton-objects.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,4 @@ When using a companion object from Java code, the members will be defined in a c
206206

207207
## More resources
208208

209-
* Learn more about Companion objects in the [Scala Book](/overviews/scala-book/companion-objects.html)
209+
* Learn more about Companion objects in the [Scala Book](/scala3/book/domain-modeling-tools.html#companion-objects)

0 commit comments

Comments
 (0)