我有一个采用通用类型并返回该类型的抽象类:
abstract class Foo {
def apply[T]:T
}
class FooImpl extends Foo {
def apply[Int]: Int = 1
}
但是错误:
error: type mismatch;
found : Int(1)
required: Int
class FooImpl { def apply[Int]: Int = 1 }
为什么会发生?我该如何解决?
答案 0 :(得分:3)
您要声明一个名为Int
的类型参数,然后将其用作返回类型。因此它不同于scala.Int
。
我认为这种情况下的解决方案是将类型参数T
移至类而不是方法:
abstract class Foo[T] {
def apply: T
}
class FooImpl extends Foo[Int] {
def apply: Int = 1
}
答案 1 :(得分:1)
Bubletan已经解释了为什么它不能与用作类型参数名称的Int
一起使用。
如果您不想向Foo
添加任何类型参数,则可以做几件事。
使用类型成员:
abstract class Foo {
type T
def apply: T
}
class FooImpl extends Foo {
type T = Int
def apply: T = 1
}
这使您可以在多种方法中使用公用类型T
。
您可以只在界面中使用Any
,然后在实现中指定更精确的类型:
abstract class Foo {
def apply: Any
}
class FooImpl extends Foo {
def apply: Int = 1
}
val x: Int = (new FooImpl).apply
在这里,当编译器看到Int
上调用的方法apply
时,编译器将能够正确推断出更具体的类型FooImpl
。
是否可以保留T
作为参数?然后,您必须在方法apply
中添加至少某种隐式参数,以使您可以生成T
:
trait CanCreate[T] {
def create: T
}
trait Foo {
def apply[T](implicit c: CanCreate[T]): T = c.create
}
没有其他使您能够生成T
实际实例的参数,您所能做的就是抛出异常(从而“返回Nothing
”)。