【发布时间】:2019-03-06 01:42:11
【问题描述】:
我有以下代码,它应该是一个工厂类。它的 apply 方法有一个泛型参数用于返回类型限制:
sealed trait Account
final case class CheckingAccount() extends Account
final case class SavingsAccount() extends Account
object Account {
def apply[T <: Account]:T = {
CheckingAccount() // CheckingAccount().asInstanceOf[T]
}
}
但如果不显式进行类型转换,编译器会报告“Banking.CheckingAccount 类型的表达式不符合执行的类型 T”。有人知道为什么吗?
【问题讨论】:
-
如果您将方法
apply调用为Account.apply[SavingsAccount],它不会返回SavingsAccount,那么为什么要对它进行类型检查? -
那个函数体只是一个例子,它可能会返回任何子类型给 Account。
-
如果它可能返回
Account的任何子类型,那么返回类型应该是Account。这不是您的函数签名在此示例中所说明的内容。 -
很多事情都是可能的。但是,如果您承诺准确返回您被要求的
T,则当您被要求提供SavingsAccount时,您不能返回CheckingAccount。因此,您的方法不会进行类型检查。而且,很容易看出签名为def apply[T <: Account]: T的方法必须总是抛出异常,因为Nothing <: Account,而你保证Account.apply[Nothing]会返回一个Nothing,这是不可能的(除非您通过抛出异常或错误来保证您的方法永远不会返回)。 -
这可能是 X-Y 问题。你为什么要客户命名别的东西?用例是什么?客户如何告诉方法它想要什么? (该方法当然必须返回其类型签名所说的返回值,毕竟它是一种类型安全的语言)
标签: scala generics types casting