斯卡拉的上限

时间:2017-07-23 11:54:30

标签: scala

我正在尝试为变量设置上限。

trait Container {
type A <: Number
def value: A
}

然后当我尝试为我的

获取一个值时
object AnyNumber extends Container {
def value = 2
}

我收到此错误

<console>:25: error: overriding type A in trait Container with bounds <: Number;
 type A has incompatible type
   type A = Int
        ^

3 个答案:

答案 0 :(得分:2)

您收到此错误是因为Int不是Number的子类型,这是您要放置的约束。

如果您想使用可隐式转换为数字类型的类型成员,我会在Numeric[A]上使用value隐含证据:

trait Container {
  type A
  def value(implicit ev: Numeric[A]): A
}

object AnyNumber extends Container {
  type A = Int
  override def value(implicit ev: Numeric[Int]): Int = 2
}

注意我使用的是Numeric[A]而不是Number,这是Scala的等效内容。现在这将有效:

def main(args: Array[String]): Unit = {
  val intRes = AnyNumber.value
}

但是尝试将其与String一起使用不会编译:

def main(args: Array[String]): Unit = {
  val strRes = StringNumber.value
}

结果:

Error:(24, 31) could not find implicit value for parameter ev: Numeric[String]
    val strRes = StringNumber.value

答案 1 :(得分:0)

scala.Int仅展开scala.AnyVal,而您的上限为java.lang.Number

解决方法是使用java.lang.Integer代替scala.Int,因为它满足您的边界(java.lang.Number

例如

trait Container {
  type A <: Number
  def value: A
}

object AnyNumber extends Container {
  type A = Integer
  def value = 2
}

AnyNumber.value shouldBe 2

答案 2 :(得分:0)

如果Container成为一个班级而不是特质可以接受,以下内容接近于Yuval的答案,但更符合人体工程学:

abstract class Container[A: Numeric] {
  // optional, if you need a type member specifically
  type _A = A
  def value: A
}

object AnyNumber extends Container[Int] {
  def value = 2
}

如果要隐藏API中的泛型参数,可以执行以下操作:

sealed trait Container {
  type A
  val ev: Numeric[A]
  def value: A
}

abstract class ContainerImpl[B](implicit val ev: Numeric[B]) extends Container {
  type A = B
}