Generics 未知类型的最小/最大值

Generics 未知类型的最小/最大值,generics,scala,Generics,Scala,是否可以获取未知类型T的MinValue-或MaxValue?如Int中的Int.MinValue和Int.MaxValue 谢谢您不能对任意类型执行此操作,因为只有少数类型(即,有一个最大值和一个最小值)。现在,如果您不知道它是Int还是Double或其他数值,您可以执行模式匹配: def maxValue[T <: AnyRef](t:T) = t match { case x:Int => Int.MaxValue case x:Double => Dou

是否可以获取未知类型T的
MinValue
-或
MaxValue
?如
Int
中的
Int.MinValue
Int.MaxValue


谢谢

您不能对任意类型执行此操作,因为只有少数类型(即,有一个最大值和一个最小值)。现在,如果您不知道它是Int还是Double或其他数值,您可以执行模式匹配:

def maxValue[T <: AnyRef](t:T) = t match {
    case x:Int => Int.MaxValue
    case x:Double => Double.MaxValue
    case x:Byte => Byte.MaxValue
    case x:Short => Short.MaxValue        
    case x:Long => Long.MaxValue
    case x:Float => Float.MaxValue
    case x:Char => Char.MaxValue
    case _ => -1
}
def maxValue[T Int.maxValue
案例x:Double=>Double.MaxValue
案例x:Byte=>Byte.MaxValue
案例x:Short=>Short.MaxValue
案例x:Long=>Long.MaxValue
案例x:Float=>Float.MaxValue
案例x:Char=>Char.MaxValue
案例号=>-1
}

或者类似的东西。

正如@mpilquist在上面的评论中所说,您可以创建一个
有界的
类型class a la Haskell

代码示例:

trait Bounded[A] {
  def minValue: A
  def maxValue: A
}

object Bounded {
  def apply[A](min: A, max: A) = new Bounded[A] {
    def minValue = min
    def maxValue = max 
  }  

  implicit val intBounded = Bounded(Int.MinValue, Int.MaxValue)
  implicit val longBounded = Bounded(Long.MinValue, Long.MaxValue)
}

object Main {
  def printMinValue[A : Bounded](): Unit = {
    println(implicitly[Bounded[A]].minValue)
  }

  def main(args: Array[String]): Unit = {
    printMinValue[Int]() // prints -2147483648
    printMinValue[Long]() // prints -9223372036854775808
  }
}

附录:

您甚至可以将其扩展到自定义类型,如下所示:

// A WeekDay ADT
sealed abstract trait WeekDay
case object Mon extends WeekDay
case object Tue extends WeekDay
case object Wed extends WeekDay
case object Thu extends WeekDay
case object Fri extends WeekDay
case object Sat extends WeekDay
case object Sun extends WeekDay

object WeekDay {
  implicit val weekDayBounded = Bounded[WeekDay](Mon, Sun)
}

printMinValue[WeekDay]() // prints Mon

任意类型
T
的最大值是多少?没有答案,因为
DatabaseConnection
类没有最大值。您可以使用类型类来告诉编译器某些类型的最大值是多少。这似乎通过一个示例得到了最好的解释

abstract class Limit[T] {
  val min: T
  val max: T
}

implicit object IntLimits extends Limit[Int] {
  val min = Int.MinValue
  val max = Int.MaxValue
}

implicit object DoubleLimits extends Limit[Double] {
  val min = Double.MinValue
  val max = Double.MaxValue
}
可以按如下方式使用此类型类:

def printMax[T: Limit] {
  println(implicitly[Limit[T]].max)
}
printMax[Int] // prints 2147483647
printMax[Double] // prints 1.7976931348623157E308
类型类最酷的一点是,您甚至可以在自定义类上使用它们,例如,在库中充当索引的类:

// the class definition somewhere
case class Index(key: String)

// the definition of the limit values (potentially) somewhere else 
implicit object IndexLimits extends Limit[Index] {
  val min = Index("AA")
  val max = Index("ZZ")
}

printMax[Index] // prints Index(ZZ)
是否可以获取未知类型T的最小值或最大值


不,它不是,原因很简单,如果
t
未知,那么你怎么知道它甚至有一个最小值或最大值呢?

你可以尝试转换为int并检查该值的最小值和最大值。你可以创建一个有界类型类,类似于Haskell的:不适用于Java-所有数字类型类都有最大值和最小值。但是它是s按惯例-不是共享接口或基类。@Ed:Java的MIN_值不可用,因为它在不同的类中表示不同的内容。Scala修复了这一点。@soc:如果语句“Scala(和Java)只有Double和Int[具有MaxValue和MinValue]”如果是真的,那就没有什么意义了。但是看起来Scala也不是这样的-对吗?你说的“不同的东西”是什么意思在Java中-每个类返回对应基元类型的值?@Ed Staub:Java和Scala对所有数值类型都有
MinValue
/
MaxValue
。但是Java的值不一致,例如Java中的
minu value
在整数/浮点情况下有不同的语义,而在Scala
MinValue
的行为与预期一致。“这些值实际上是该类型变量在所有情况下的最小值和最大值”因此在Java中是非常错误的。例如,将
Java.lang.Double.minu VALUE
Double.MinValue
进行比较。这些定义也很有用:
def maxValue[a:Bounded]=隐式[Bounded[A]].maxValue
def minValue[A:Bounded]=隐式[Bounded[A]].minValue