Рубрики
Без рубрики

Отклонения в Scala

Scala поддерживает использование параметров типа для реализации классов и функций, которые могут поддерживать несколько t… С тегами scala, java, jvm, функциональный.

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

Что такое Дисперсия?

Дисперсия – это соотношение отношений подтипов сложных типов и отношений подтипов их составных типов. Дисперсия – это соотношение отношений подтипов сложных типов и отношений подтипов их составных типов.

Другими словами, дисперсия позволяет разработчикам моделировать отношения между типами и типами компонентов. Как следствие, дисперсия позволяет создавать чистые и очень удобные универсальные классы, которые широко используются в различных библиотеках Scala.

Scala поддерживает три типа дисперсии: ковариация , инвариантность и контравариантность . Имея это в виду, давайте рассмотрим каждый из них более подробно.

Ковариация

Давайте предположим, что у нас есть следующая структура классов

    abstract class Vehicle {
      def name: String
    }
    case class Car(name: String) extends Vehicle
    case class Bus(name: String) extends Vehicle

    class VehicleList[T](val vehicle: T)

Автомобиль и Классы Bus оба наследуются от абстрактного класса Транспортное средство . Учитывая, что у автомобиля класса есть своя коллекция Список транспортных средств[Автомобиль] : является ли Список транспортных средств[Автомобиль] подтипом Список транспортных средств[Автомобиль] ? Мой ответ – нет. Несмотря на то, что Автомобиль класс расширяет Транспортное средство класс, этого нельзя сказать о Список транспортных средств[Автомобиль] и Список транспортных средств [Транспортное средство] .

    val vehicleList: VehicleList[Vehicle] = new VehicleList[Car](new Car("bmw")) // incorrect: type mismatch

Решение этой проблемы заключается в использовании ковариации . Как следствие, Список транспортных средств [Автомобиль] будет подтипом Список транспортных средств [Транспортное средство] . Это обеспечивает больший полиморфизм с универсальными типами. Чтобы составить Список транспортных средств класс T параметр ковариантный, просто добавьте небольшой знак + вдоль типа:

    class VehicleList[+T](val vehicle: T)

    val vehicleList: VehicleList[Vehicle] = new VehicleList[Car](new Car("bmw")) // correct

Контравариантность

В отличие от ковариации, контравариантность допускает общий тип T быть T или супертип T . Например, давайте рассмотрим пример класса, аналогичного тому, который использовался выше:

    class CarList[T](val car: T)

Класс CarList ожидает получить параметр типа T и никакого другого супер- или подтипа. Что делать, если мы хотим использовать Список автомобилей[Автомобиль] класс для хранения экземпляров класса транспортных средств, а также?

    val carList: CarList[Car] = new CarList[Vehicle](new Vehicle("boat")) // incorrect: type mismatch

Чтобы решить эту проблему, вместо знака + в определении типа используйте знак -.

    class CarList[-T](val car: T)

    val carList: CarList[Car] = new CarList[Vehicle](new Vehicle("boat")) // correct

Инвариантность

Инвариантность – это отношение универсального типа по умолчанию T . Список [Автомобиль] принимает только Автомобиль тип – любой супертип или подтип не принимается.

    class List[T](val t: T)

Резюме

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

Оригинал: “https://dev.to/bartoszgajda55/variances-in-scala-e8o”