我想摆脱运行时强制转换为泛型 ( asInstanceOf[A]
) 而不进行隐式转换。
当我有一个由具有共同特征的案例类组成的相当干净的数据模型并希望在其上实现通用算法时,就会发生这种情况。例如,生成的算法应该采用一个类型的类,A
它是 的子类,trait T
并且应该返回A
具有一些更新字段的具体类的副本。
copy
当我可以简单地向基本特征添加一个抽象方法并在所有子类中实现它时,这很容易实现。但是,这可能会使用某些算法所需的方法污染模型,并且有时是不可能的,因为模型可能超出我的控制范围。
这是一个简化的示例,用于演示问题和使用运行时强制转换的解决方案。
请不要纠结于细节。
假设有一个特征和一些我无法更改的案例类:
trait Share {
def absolute: Int
}
case class CommonShare(
issuedOn: String,
absolute: Int,
percentOfCompany: Float)
extends Share
case class PreferredShare(
issuedOn: String,
absolute: Int,
percentOfCompany: Float)
extends Share
percentOfCompany
并且这里有一个简单的方法,当总股数发生变化时重新计算当前并更新案例类中的字段
def recalculateShare[A <: Share](share: A, currentTotalShares: Int): A = {
def copyOfShareWith(newPercentage: Float) = {
share match {
case common: CommonShare => common.copy(percentOfCompany = newPercentage)
case preferred: PreferredShare => preferred.copy(percentOfCompany = newPercentage)
}
}
copyOfShareWith(share.absolute / currentTotalShares.toFloat).asInstanceOf[A]
}
REPL 上的一些示例调用:
scala> recalculateShare(CommonShare("2014-01-01", 100, 0.5f), 400)
res0: CommonShare = CommonShare(2014-01-01,100,0.25)
scala> recalculateShare(PreferredShare("2014-01-01", 50, 0.5f), 400)
res1: PreferredShare = PreferredShare(2014-01-01,50,0.125)
所以它可以工作,据我所知,.asInstanceOf[A]
调用永远不会失败,但需要编译代码。有没有办法在没有隐式转换的情况下以类型安全的方式避免运行时强制转换?