2015-10-13 3 views
2

У меня есть переменная какого-либо типа, и я хотел бы получить информацию от объекта-компаньона. Например, я думал, что я мог бы быть в состоянии сделать что-то вроде этого:Доступ к сопутствующему объекту типа

def foo[I: Integral](i:I): = { 
    val minVal = i match { 
    case _:Byte => Byte.MinValue 
    case _:Char => Char.MinValue 
    case _:Int => Int.MinValue 
    case _:Long => Long.MinValue 
    case _:Short => Short.MinValue 
    } 
    // compare i and minVal 
} 

Но это довольно многословным и minVal выходит как :Long, что затрудняет сравнение с i: I.

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

ответ

4

Вы можете использовать класс типа, чтобы получить Minumum значение:

trait MinValue[T] { def minValue: T } 
object MinValue { 
    implicit val minByte = new MinValue[Byte] { def minValue = Byte.MinValue } 
    implicit val minChar = new MinValue[Char] { def minValue = Char.MinValue } 
    implicit val minLong = new MinValue[Long] { def minValue = Long.MinValue } 
    implicit val minInt = new MinValue[Int] { def minValue = Int.MinValue } 
} 

Мы можем использовать этот класс типа, чтобы получить Minumum значение для типа значения, переданного foo функции:

def foo[I: Integral](i: I)(implicit min: MinValue[I]) = 
    implicitly[Integral[I]].compare(i, min.minValue) 
// or 
def foo2[I: Integral: MinValue](i: I) = { 
    val minVal = implicitly[MinValue[I]].minValue 
    implicitly[Integral[I]].compare(i, minVal) 
} 

foo(5) // Int = 1 
foo(Int.MinValue) // Int = 0 

foo2(-127.toByte) // Int = 1 
foo2(-128.toByte) // Int = 0