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
См. подробнее о Каррировании
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 есть описание Трейтов.
+ ++ В каких случаях требуется использовать трейты вместо абстрактных классов? + Если вы хотите создать тип похожий на интерфейс, то возможно вам покажется непростым занятием решить что использовать: + трейт или абстрактный класс. + Несколько правил для принятия решения: +
trait t(i: Int) {}
; параметр i
в этом коде недопустим.Вы не первый, кто задает такой вопрос. Более подробные ответы вы можете найти на +stackoverflow:Scala traits vs abstract classes, Difference between Abstract Class and Trait, +и +Programming in Scala: To trait, or not to trait? +
+Ранее вы могли видеть, что мы определили функцию, принимающая тип Int
, который является одним из видов Number. Функция может быть объявлена как обобщенная (generic) и после этого может работать с любым типом. Когда объявлена такая функция, вы увидите
параметр-типразмещенный внутри квадратных скобок:
-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) ++