我正在尝试为变量设置上限。
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
^
答案 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
}