В Scala мы знаем, что если мы не определяем тип переменной, то она сама принимает свой тип,

[code language="scala"]
scala› val name = "John"
name: String = John
[/code]
Однако мы можем контролировать тип значения также быть byte, int или string,

[code language="scala"]
scala› val name: String = "John"
name: String = John

scala› val age: Int = 25
age: Int = 25

scala› val оклад: Double = 25000.0
оклад: Double = 25000.0
[/code]
Если мы делаем код для использования желаемой формы, мы набираем следующее,

[code language="scala"]
scala› val bonus = 5000,75 : Двойной
бонус: Двойной = 5000,75

scala› val name = «John» : String
name: String = John
[/code]
Как мы видим, компилятор предоставляет определение типа так, как нам нужно, но когда мы хотите предоставить собственное определение или переопределить тип значения, тогда мы также можем использовать аннотации типов.

Приписка

Scala Ascription — это тот же подход, что и аннотации, но с небольшим отличием. Иногда начинающего разработчика Scala могут сбить с толку как аннотации, так и приписывания. Приписывание можно рассматривать как процесс преобразования типа, а аннотации — как простой способ определения результата, который мы хотим получить от выражения после его выполнения.

В следующих примерах мы можем ясно показать приписывание.

У нас есть премия по типу Double и зарплата по типу объекта. Как вы можете видеть здесь, мы хотим, чтобы зарплата имела тип Object, в противном случае она не должна быть скомпилирована с типом String или unmatching.

[code language="scala"]
scala› val бонус: Двойной = 3000,75
бонус: Двойной = 3000,75

scala›val оклад = бонус: объект
оклад: объект = 3000,75

scala› val name: String = «John»
name: String = John

scala› val оклад = имя: Double
‹console›:8: ошибка: несоответствие типа;
найдено: строка
требуется: Double
val оклад = имя: Double
[/code]
Теперь взгляните на приведенный ниже пример, где Ascription можно применить другим способом,

[code language="scala"]
val numberList = (от 1 до 5).toList

numberList.foldLeft(Nil: List[Int]) {
(table, currentNumber) =› table :+ (currentNumber * 2)
}

numberList.headOption.fold(Left("Список пуст"): Both[String, Int]) {
number =› Right(number * 2)
}
[/code]< br /> В приведенном выше коде мы использовали (Nil: List[Int]) и (Left("List is empty"): Both[String, Int]) другие примеры приписок.

Добавление методов в класс неявным способом

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

[code language="scala"]
scala› class BetterWay(val s: String) {
| def increment = s.map(c =› (c + 1).toChar)
| }
определенный класс BetterWay
[/code]
Здесь мы определяем класс BetterWay, имеющий методы, которые возвращают следующий позиционированный символ из стандартов ASCII для каждого отдельного символа входного слова.

Теперь мы определяем магию ниже,

[code language=”scala”]
scala› неявное определение stringToString(s: String) = new BetterWay(s)
предупреждение: было одно предупреждение о функции; повторный запуск с -feature для подробностей
stringToString: (s: String)BetterWay
[/code]
Здесь мы определили метод stringToString, который принимает входную строку и передает ее в BetterWay. класса для дальнейшей обработки. Теперь мы предоставляем некоторые данные для проверки,

[code language=”scala”]
scala› “hal”.increment
res0: String = ibm
[/code]
Наконец мы вставили слово hal и получили все символов этого увеличивается на единицу и приводит к значениям ASCII ibm.

Давайте посмотрим, что здесь происходит…

Метод stringToString — это простые методы, определенные в Scala. Но так как он определен по ключевому слову implicit, то у него есть нечто большее. Неявное делает магию здесь,

Метод, определенный как неявный, в нашем случае stringToString, берет строку, ищет класс BetterWay и ищет каждый метод, который принимает строку в качестве параметра.
Методы приращения, определенные в классе, обрабатывают строку, перебирают каждый из его символ, а затем получает символ рядом с ним из значений ASCII.
Неважно, какое имя вы указываете для имени метода для stringToString.

Исправление обезьяны

Теперь, когда у нас есть представление об имплицитах и ​​о том, как они работают и выполняют свою задачу, мы возьмем под контроль аналогичную концепцию Monkey Patching. Если пользователь имеет опыт работы с Ruby, то он всегда находит имплициты как еще один способ исправления обезьян. Monkey Patching в ruby ​​используется для расширения существующего класса без создания нового класса. Теперь взгляните на приведенный ниже пример,

[code language="scala"]
объект NumberDefinition расширяет приложение {

неявный класс DefinitionHelper(val num: Int) {
def isEven = {
num % 2 == 0
}

def isOdd = {
число % 2 != 0
}
}

50.isEven // true
51.isOdd // true
}
[/code]
Здесь мы определили неявный класс DefinitionHelper, который принимает значение типа Int. , что приводит к тому, что класс наследует все члены Int и преобразует любой Int в области определения в DefinitionHelper.

Большая разница между Ruby и Scala заключается в том, что Scala применяет неявное в текущей области видимости. Мы можем вызывать и импортировать имплициты где угодно, не засоряя глобальное пространство имен, что приводит к меньшему количеству коллизий и более компактным DSL.

При объявлении имплицитов в Scala необходимо помнить о следующих моментах:

  • Имплициты должны быть определены внутри другого трейта, класса или любого объекта.
  • У нас может быть только один неявный параметр в конструкторе,
  • Scala определяет то же имя, что и класс, для объекта в качестве сопутствующего объекта. Помня об этом, у нас не может быть другого объекта или члена с тем же именем, что и у класса в области видимости.

Поэтому я думаю, что этот блог очень поможет вам в расширении возможностей scala с помощью системы типов и имплицитов.

Удачного ведения блога!!!