Изначально планировал, что на месте этого поста будет сравнение двух подходов к реализации полиформизма: композиции и наследования. Но, пока искал материал, наткнулся на гораздо более животрепещущий топик.
Одним из самых острых вопросов для jvm-программистов на сегодняшний день является уменьшение количества аллокаций в системе. Если не придавать значение числу создаваемых объектов, то можно столкнуться с небезызвестными "GC-подвисаниями", когда сборщик мусора забирает всё процессорное время для удаления ненужных объектов.
Естественно, данная проблема не обошла и Scala. Поскольку в языке нет примитивов, количество используемой памяти могло бы возрастать непозволительно быстро. К счастью, "волшебный" trait AnyVal
, наследуемый такими типами как Int
, Long
и т.д., позволяет превратить любой класс с одним value
-параметром в обёртку, которая во время исполнения программы не инстанцинируется (все методы такого класса становятся статическими).
На самом деле, это, конечно, работает далеко не всегда. В документации выделяют три случая, когда обёртка (value
-класс) всё-таки превращается в полноценный объект:
1. Value
-класс рассматривается как объект другого типа.
2. Value
-класс помещён в массив
3. Проверка типа value
-класса во время исполнения программы (например, паттерн матчинг)
Максимально подробные тесты можно найти по ссылке, однако в качестве простого примера, когда объект-обёртка будет создан (по правилу 1), можно привести следующий код:
object Test {К счастью (нет, я не специально выбираю такие темы), в Scala 3 появятся
case class Value(value: Int) extends AnyVal
def identity[A](a: A): A = a
println(identity(Value(1))
}
Opaque types
- конструкция языка, гарантирующая отсутствие обёртки при исполнении программы. На текущий же момент рекомендуется просто с умом использовать AnyVal
(или, например, такие конструкции, как типы с тэгами) и прежде всего тестировать, какое реальное влияние оказывает AnyVal
на быстродействие в программе.
>>Click here to continue<<
