You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Абстрактные типы, такие как трейты и абстрактные классы, которые могут содержать членов абстрактного типа.
18
-
Это означает, что только конкретный экземпляр определяет, каким именно будет этот тип.
17
+
Абстрактные типы, такие как трейты и абстрактные классы, могут содержать членов абстрактного типа.
18
+
Абстрактный означает, что только конкретный экземпляр определяет, каким именно будет тип.
19
19
Вот пример:
20
20
21
21
```tut
@@ -24,7 +24,7 @@ trait Buffer {
24
24
val element: T
25
25
}
26
26
```
27
-
Здесь мы определили абстрактный вариант тип `T`, который используется для описания типа `element`. Мы можем расширить его в абстрактном классе, добавив верхнюю границу связанного с `T` типа, чтобы сделать его более конкретным.
27
+
Здесь мы определили абстрактный тип `T`, который используется для описания типа члена `element`. Мы можем расширить его в абстрактном классе, добавив верхнюю границу нового типа `U`связанного с `T`, делая описание типа более конкретным.
28
28
29
29
```tut
30
30
abstract class SeqBuffer extends Buffer {
@@ -33,9 +33,9 @@ abstract class SeqBuffer extends Buffer {
33
33
def length = element.length
34
34
}
35
35
```
36
-
Обратите внимание, как мы можем использовать еще один абстрактный тип `type U` в качестве верхней границы типа. Класс `SeqBuffer` позволяет хранить в буфере только последовательности, указывая, что тип `T` должен быть подтипом `Seq[U]` для нового абстрактного типа `U`.
36
+
Обратите внимание, как мы можем использовать новый абстрактный тип `U` в качестве верхней границы типа. Класс `SeqBuffer` позволяет хранить в буфере только последовательности, указывая, что тип `T` должен быть подтипом `Seq[U]` для нового абстрактного типа `U`.
37
37
38
-
[Трейты](traits.html) или [классы](classes.html) с абстрактными членами типа часто используются в сочетании с анонимными экземплярами классов. Чтобы проиллюстрировать это рассмотрим программу, которая имеет дело с буфером, который ссылается на список целых чисел:
38
+
[Трейты](traits.html) или [классы](classes.html) с членами абстрактного типа часто используются в сочетании с анонимными экземплярами классов. Чтобы проиллюстрировать это рассмотрим программу, которая имеет дело с буфером, который ссылается на список целых чисел:
39
39
40
40
```tut
41
41
abstract class IntSeqBuffer extends SeqBuffer {
@@ -52,9 +52,9 @@ val buf = newIntSeqBuf(7, 8)
52
52
println("length = " + buf.length)
53
53
println("content = " + buf.element)
54
54
```
55
-
Здесь класс `newIntSeqBuf`является создателем экземпляров `IntSeqBuffer`, использует анонимную реализацию класса `IntSeqBuffer` (т.е. `new IntSeqBuffer`), устанавливая тип `T` как `List[Int]`.
55
+
Здесь класс `newIntSeqBuf`создает экземпляры `IntSeqBuffer`, используя анонимную реализацию класса `IntSeqBuffer` (т.е. `new IntSeqBuffer`), устанавливая тип `T` как `List[Int]`.
56
56
57
-
Мы можем выводить тип класса из типа его членов и наоборот наоборот. Приведем версию кода, в которой выводится тип класса из типа его члена:
57
+
Мы можем вывести тип класса из типа его членов и наоборот. Приведем версию кода, в которой выводится тип класса из типа его члена:
Обратите внимание, что здесь нам необходимо использовать [вариантность в описании типа](variances.html) (`+T <: Seq[U]`) для того, чтобы скрыть конкретный тип реализации последовательности объектов, возвращаемых из метода `newIntSeqBuf`.
77
+
Обратите внимание, что здесь необходимо использовать [вариантность в описании типа](variances.html) (`+T <: Seq[U]`) для того, чтобы скрыть конкретный тип реализации списка, возвращаемого из метода `newIntSeqBuf`.
Copy file name to clipboardExpand all lines: _ru/tour/annotations.md
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -57,14 +57,14 @@ def factorial(x: Int): Int = {
57
57
58
58
59
59
## Аннотации, влияющие на генерацию кода
60
-
Некоторые аннотации типа `@inline` влияют на сгенерированный код (т.е. ваш jar-файл может иметь другой код, чем если бы вы не использовали аннотацию). Такая аннотация означает вставку всего кода в тело метода вместо вызова. Полученный байт-код длиннее, но, надеюсь, работает быстрее. Использование аннотации `@inline` не гарантирует, что метод будет встроен, но заставит компилятор сделать это, если и только если будут соблюдены некоторые практические требования к размеру сгенерированного кода.
60
+
Некоторые аннотации типа `@inline` влияют на сгенерированный код (т.е. в результате сам код вашего jar-файл может отличаться). Такая аннотация означает вставку всего кода в тело метода вместо вызова. Полученный байт-код длиннее, но, надеюсь, работает быстрее. Использование аннотации `@inline` не гарантирует, что метод будет встроен, но заставит компилятор сделать это, если и только если будут соблюдены некоторые разумные требования к размеру сгенерированного кода.
61
61
62
62
### Java аннотации ###
63
63
Есть некоторые отличий синтаксиса аннотаций, если пишется Scala код, который взаимодействует с Java.
64
64
65
65
**Примечание:**Убедитесь, что вы используете опцию `-target:jvm-1.8` с аннотациями Java.
66
66
67
-
Java имеет определяемые пользователем метаданные в виде [аннотаций](https://docs.oracle.com/javase/tutorial/java/annotations/). Ключевой особенностью аннотаций является то, что они полагаются на указание пар ключ-значение для инициализации своих элементов. Например, если нам нужна аннотация для отслеживания источника какого-то класса, мы можем определить её как
67
+
Java имеет определяемые пользователем метаданные в виде [аннотаций](https://docs.oracle.com/javase/tutorial/java/annotations/). Ключевой особенностью аннотаций является то, что они задаются в виде пар ключ-значение для инициализации своих элементов. Например, если нам нужна аннотация для отслеживания источника какого-то класса, мы можем определить её как
68
68
69
69
```
70
70
@interface Source {
@@ -98,7 +98,7 @@ class MyScalaClass ...
98
98
}
99
99
```
100
100
101
-
А затем использовать следующим образом
101
+
А затем можно использовать следующим образом
102
102
103
103
```
104
104
@SourceURL("http://coders.com/")
@@ -112,7 +112,7 @@ public class MyClass extends HisClass ...
112
112
class MyScalaClass ...
113
113
```
114
114
115
-
Элемент `mail` был указан со значением по умолчанию, поэтому нам не нужно явно указывать его значение. Однако, если нам нужно это сделать, мы не можем смешивать эти два стиля в Java:
115
+
Элемент `mail` был указан со значением по умолчанию, поэтому нам не нужно явно указывать его значение. Мы не можем смешивать эти два стиля в Java:
Результаты выражений можно назвать с помощью ключевого слова `val`.
50
+
Результаты выражений можно присваивать именам с помощью ключевого слова `val`.
51
51
52
52
```tut
53
53
val x = 1 + 1
@@ -63,7 +63,7 @@ println(x) // 2
63
63
x = 3 // Не компилируется.
64
64
```
65
65
66
-
Типы значений могут быть выведены автоматически, но вы также можете явно указать тип, как показано ниже:
66
+
Типы значений могут быть выведены автоматически, но можно и явно указать тип, как показано ниже:
67
67
68
68
```tut
69
69
val x: Int = 1 + 1
@@ -73,15 +73,15 @@ val x: Int = 1 + 1
73
73
74
74
### Переменные
75
75
76
-
Переменные похожи на значения константы, за исключением того, что их можно переназначить заново. Вы можете объявить переменную с помощью ключевого слова `var`.
76
+
Переменные похожи на значения константы, за исключением того, что их можно присваивать заново. Вы можете объявить переменную с помощью ключевого слова `var`.
77
77
78
78
```tut
79
79
var x = 1 + 1
80
80
x = 3 // Компилируется потому что "x" объявлен с ключевым словом "var".
81
81
println(x * x) // 9
82
82
```
83
83
84
-
Как и в случае со значениями, вы можете явно указать тип, если хотите:
84
+
Как и в случае со значениями, вы можете явно указать тип, если захотите:
85
85
86
86
```tut
87
87
var x: Int = 1 + 1
@@ -190,7 +190,7 @@ class Greeter(prefix: String, suffix: String) {
190
190
println(prefix + name + suffix)
191
191
}
192
192
```
193
-
Возвращаемый тип метода `greet` это `Unit`, используется тогда, когда не имеет смысла что-либо возвращать. Аналогично `void` в Java и C. (Поскольку каждое выражение Scala должно иметь какое-то значение, поэтому, при отсутствии возвращающегося значения, возвращается одиночка (сингэлтон) типа Unit. Явным образом его можно задать как `()`, оно не несет какой-либо информации.)
193
+
Возвращаемый тип метода `greet` это `Unit`, используется тогда, когда не имеет смысла что-либо возвращать. Аналогично `void` в Java и C. (Поскольку каждое выражение Scala должно иметь какое-то значение, то при отсутствии возвращающегося значения, возвращается экземпляр типа Unit. Явным образом его можно задать как `()`, он не несет какой-либо информации.)
194
194
195
195
Вы можете создать экземпляр класса используя ключевое слово `new`.
196
196
@@ -233,11 +233,11 @@ if (point == yetAnotherPoint) {
233
233
} // Point(1,2) и Point(2,2) разные.
234
234
```
235
235
236
-
Есть еще куча вещей которые мы бы хотели рассказать про классы образцы, мы уверены, что вы влюбитесь в них! Обязательно рассмотрим их подробнее немного[позже](case-classes.html).
236
+
Есть еще много деталей, которые мы бы хотели рассказать про классы образцы, мы уверены, что вы влюбитесь в них! Обязательно рассмотрим их [позже](case-classes.html).
237
237
238
238
## Объекты
239
239
240
-
Объекты задаются и существуют в единственным экземпляре. Вы можете думать о них как об одиночках своего собственного класса.
240
+
Объекты задаются и существуют в единственным экземпляре. Вы можете думать о них как об одиночках (сингэлтонах) своего собственного класса.
241
241
242
242
Вы можете задать объекты при помощи ключевого слова `object`.
243
243
@@ -260,7 +260,7 @@ val newerId: Int = IdFactory.create()
260
260
println(newerId) // 2
261
261
```
262
262
263
-
Позже рассмотрим объекты более [подробно](singleton-objects.html).
263
+
Позже мы рассмотрим объекты [подробнее](singleton-objects.html).
В то время как [верхнее ограничение типов](upper-type-bounds.html)ограничивают тип до подтипа стороннего типа, *нижнее ограничение типов* объявляют тип супертипом стороннего типа. Термин `B >: A` выражает, что параметр типа `B` или абстрактный тип `B` относится к супертипу типа `A`. В большинстве случаев `A` будет задавать тип класса, а `B` задавать тип метода.
17
+
В то время как [верхнее ограничение типа](upper-type-bounds.html)ограничивает тип до подтипа стороннего типа, *нижнее ограничение типа* объявляют тип супертипом стороннего типа. Термин `B >: A` выражает, то что параметр типа `B` или абстрактный тип `B` относится к супертипу типа `A`. В большинстве случаев `A` будет задавать тип класса, а `B` задавать тип метода.
18
18
19
19
Вот пример, где это полезно:
20
20
@@ -36,7 +36,7 @@ case class Nil[+B]() extends Node[B] {
36
36
37
37
В данной программе реализован связанный список. `Nil` представляет пустой список. Класс `ListNode` - это узел, который содержит элемент типа `B` (`head`) и ссылку на остальную часть списка (`tail`). Класс `Node` и его подтипы ковариантны, потому что у нас указанно `+B`.
38
38
39
-
Однако эта программа _не компилируется_, потому что параметр `elem` в `prepend` имеет тип `B`, который мы объявили *ко*вариантным. Так это не работает, потому что функции *контр*вариантны в типах своих параметров и *ко*вариантны типах в своих результатов.
39
+
Однако эта программа _не компилируется_, потому что параметр `elem` в `prepend` имеет тип `B`, который мы объявили *ко*вариантным. Так это не работает, потому что функции *контр*вариантны в типах своих параметров и *ко*вариантны в типах своих результатов.
40
40
41
41
Чтобы исправить это, необходимо перевернуть вариантность типа параметра `elem` в `prepend`. Для этого мы вводим новый тип для параметра `U`, у которого тип `B` указан в качестве нижней границы типа.
0 commit comments