diff --git a/ru/basics.html b/ru/basics.html index 8817f721..115b1a88 100644 --- a/ru/basics.html +++ b/ru/basics.html @@ -218,8 +218,14 @@

Каррирование функций

Вы можете взять любую функцию с множеством аргументов и произвести ее каррирование. Давайте попробуем использовать функцию, которую рассматривали раньше, например adder

-scala> (adder _).curried
-res1: (Int) => (Int) => Int = <function1>
+scala> val curriedAdd = (adder _).curried
+curriedAdd: Int => (Int => Int) = <function1>
+
+scala> val addTwo = curriedAdd(2)
+addTwo: Int => Int = <function1>
+
+scala> addTwo(4)
+res22: Int = 6
 

См. подробнее о Каррировании

Использование переменного количества аргументов

@@ -230,16 +236,18 @@

Использование переменного количества ар arg.capitalize } } + +scala> capitalizeAll("rarity", "applejack") +res2: Seq[String] = ArrayBuffer(Rarity, Applejack)

Классы

+Здесь мы объявили класс Calculator:
 scala> class Calculator {
      |   val brand: String = "HP"
      |   def add(m: Int, n: Int): Int = m + n
      | }
 
-Здесь мы объявили класс Calculator
-
 scala> val calc = new Calculator
 calc: Calculator = Calculator@e75a11
 
@@ -272,6 +280,43 @@ 

Конструктор

Обратите внимание на два различных способа написания комментариев.

Выражения

Наш пример с калькулятором дает хороший пример того, как Scala ориентирован на выражения (expression-oriented). Значение переменной color было присвоено благодаря if/else выражению. Scala сильно ориентирован на выражения: большинство вещей делается с помощью выражений, а не утверждений.

+ +

Функции и методы

+

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

+
+	scala> class C {
+     |   var acc = 0
+     |   def minc = { acc += 1 }
+     |   val finc = { () => acc += 1 }
+     | }
+defined class C
+
+scala> val c = new C
+c: C = C@1af1bd6
+
+scala> c.minc // calls c.minc()
+
+scala> c.finc // returns the function as a value:
+res2: () => Unit = 
+
+ +

+ В то время, как вы вызываете одну "функцию" без скобок, а другую - со скобками, вы можете подумать: + Упс, я думал, что знаю как работают функции в Scala, но, как оказалось, нет. Возможно, иногда им требуются скобки? + Вы можете понимать функции, но использовать методы. +

+ +

+ На практике, вы можете делать великие вещи на Scala не вдаваясь в подробности различия функций и методов. + Если вы новичок в Scala и прочитали + объяснение различий, + то, возможно у вас будут проблемы с ними. Это не значит, что у вас возникнут проблемы с использованием Scala. + Это только означает, что различия между функциями и методами достаточно тонкие, что их разъяснение могут погрузить вас в глубинные части языка. +

+

Наследование

 class ScientificCalculator(brand: String) extends Calculator(brand) {
@@ -285,6 +330,34 @@ 

Перегрузка методов

def log(m: Int): Double = log(m, math.exp(1)) }
+ +

Абстрактные классы

+

+ Вы можете определять абстрактные классы. Абстракные классы определяют содержат методы, но не реализуют их. + Однако, подклассы, наследующиеся от абстрактного класса, содержат реализацию этих методов. + Создать экземпляр абстрактного класса запрещено. +

+ +
+	scala> abstract class Shape {
+     	|   def getArea():Int    // subclass should define this
+     	| }
+	defined class Shape
+	
+	scala> class Circle(r: Int) extends Shape {
+	     |   def getArea():Int = { r * r * 3 }
+	     | }
+	defined class Circle
+	
+	scala> val s = new Shape
+	<console>:8: error: class Shape is abstract; cannot be instantiated
+	       val s = new Shape
+	               ^
+	
+	scala> val c = new Circle(2)
+	c: Circle = Circle@65c0035b
+
+

Трейты

Трейты – это коллекция полей и методов, которые вы можете расширить или примешать к вашему классу.

@@ -299,20 +372,42 @@ 

Трейты

}

Смотрите также: В Effective Scala есть описание Трейтов.

+ +

+ В каких случаях требуется использовать трейты вместо абстрактных классов? + Если вы хотите создать тип похожий на интерфейс, то возможно вам покажется непростым занятием решить что использовать: + трейт или абстрактный класс. + Несколько правил для принятия решения: +

+

+ +

Вы не первый, кто задает такой вопрос. Более подробные ответы вы можете найти на +stackoverflow:Scala traits vs abstract classes, Difference between Abstract Class and Trait, +и +Programming in Scala: To trait, or not to trait? +

+

Типы

-

Ранее вы могли видеть, что мы определили функцию, принимающая тип Int, который является одним из видов Number. Функция может быть объявлена как обобщенная (generic) и после этого может работать с любым типом. Когда объявлена такая функция, вы увидите

параметр-тип
размещенный внутри квадратных скобок:
-Вы можете думать о них, как о множестве параметров-типов. Рассмотрим пример трейта Кэш (Cache), который принимает параметры-типы (K, V) для ключей и их значений.

-
-trait Cache[K, V] {
-  def get(key: K): V
-  def put(key: K, value: V)
-  def delete(key: K)
-}
-
-

Методы тоже могут иметь параметры-типы

-
-def remove[K](key: K)
-
+

+ Ранее вы могли видеть, что мы определили функцию, принимающая тип Int, который является одним из видов Number. + Функция может быть объявлена как обобщенная (generic) и после этого может работать с любым типом. Когда объявлена такая функция, вы увидите параметр-тип размещенный внутри квадратных скобок. + Трейт, описанный ниже, описывает кеш с параметрами-типами для ключа и значения этого кеша [K, V]: +

+	  trait Cache[K, V] {
+	    def get(key: K): V
+	    def put(key: K, value: V)
+	    def delete(key: K)
+	  }
+	
+ Методы так же могут иметь параметры-типы. +
+		def remove[K](key: K)
+	
+