Scala 2.10 вводит классы значений, которые вы указываете, создавая расширение класса AnyVal
. Существует много ограничений на классы значений, но одним из их огромных преимуществ является то, что они позволяют методы расширения без штрафа за создание нового класса: если не требуется бокс, например. чтобы поместить класс значения в массив, это просто старый класс плюс набор методов, которые принимают класс в качестве первого параметра. Таким образом,
implicit class Foo(val i: Int) extends AnyVal {
def +*(j: Int) = i + j*j
}
разворачивается к чему-то, что может быть не дороже, чем писать i + j*j
самостоятельно (как только JVM встраивает вызов метода).
К сожалению, одно из ограничений в SIP-15, которое описывает классы значений
- Основной тип C не может быть классом значений.
Если у вас есть класс значений, который вы можете использовать, скажем, в качестве способа обеспечения безопасных типов без накладных расходов на бокс (если это вам действительно не нужно):
class Meter(val meters: Double) extends AnyVal {
def centimeters = meters*100.0 // No longer type-safe
def +(m: Meter) = new Meter(meters+m.meters) // Only works with Meter!
}
то есть ли способ обогатить Meter
без накладных расходов объекта? Ограничение в SIP-15 предотвращает очевидное
implicit class RichMeter(m: Meter) extends AnyVal { ... }
подход.