Scala 如何在获取泛型的同时传入子 class 然后 return 相同的子 class 类型?
Scala how to pass in child class and then return the same child class type while getting it generic?
我有一个这样的方法定义
def batchCacheable[T: ClassTag](cacheKeys: Seq[CacheKey])(callServiceToFetchValues: Seq[CacheKey] => Try[Map[CacheKey, T]]): Try[Map[CacheKey, T]]
其中 CacheKey 是一个定义为具有称为 buildCacheKey 的单一方法的特征,我有一个案例 class 扩展了该特征并在其中也有一个 id。
trait CacheKey {
def buildCacheKey: String
}
case class IDCacheKey(id: String) extends CacheKey {
override def buildCacheKey: String = {
s"CacheKey:$stringId"
}
}
而我想为callServiceToFetchValues
使用的函数需要IDCacheKey来获取Id,它看起来像这样。
private def getStringsFromLMS(cacheKeys: Seq[CacheKey]): Try[Map[CacheKey, String]] = {
cacheKeys.map(_ -> _.Id)
}
因此它 returns 键 -> ID 的映射。问题是 batchCacheable 只能将 CacheKey
的 Seq 传递给它,但我需要它是 ID 的 IDCacheKey
Seq。我该怎么做?
一个简单的解决方案是做这样的事情:
def getStringsFromLMS(cacheKeys: Seq[CacheKey]): Try[Map[CacheKey, String]] = {
cacheKeys.collect { case k: IDCacheKey => k.id }
}
这将默默地忽略所有不是 IDCacheKey
的内容。如果您宁愿在输入中存在错误类型的键时抛出错误,只需将 .collect
替换为 .map
.
无论如何,这都不是正确的解决方案。声明为 expect CacheKey
的函数应该能够处理 any CacheKey
的实例,无论是什么类型。
在更一般的层面上,没有提供足够的身份信息来获取值的 CacheKey
不是很有用。
长话短说,您的 CacheKey
特征似乎需要一个抽象的 id
方法。这将以自然(和“正确”)的方式解决您的问题。
或者,您可以进一步参数化 batchCacheable
:
def batchCacheable[T, K <: CacheKey](cacheKeys: Seq[K])(
callServiceToFetchValues: Seq[K] => Try[Map[K, T]]
): Try[Map[K, T]]
这让您声明 getStringsFromLMS
接受 IDCacheKey
,并且仍然可以与 batchCacheable
一起使用
我有一个这样的方法定义
def batchCacheable[T: ClassTag](cacheKeys: Seq[CacheKey])(callServiceToFetchValues: Seq[CacheKey] => Try[Map[CacheKey, T]]): Try[Map[CacheKey, T]]
其中 CacheKey 是一个定义为具有称为 buildCacheKey 的单一方法的特征,我有一个案例 class 扩展了该特征并在其中也有一个 id。
trait CacheKey {
def buildCacheKey: String
}
case class IDCacheKey(id: String) extends CacheKey {
override def buildCacheKey: String = {
s"CacheKey:$stringId"
}
}
而我想为callServiceToFetchValues
使用的函数需要IDCacheKey来获取Id,它看起来像这样。
private def getStringsFromLMS(cacheKeys: Seq[CacheKey]): Try[Map[CacheKey, String]] = {
cacheKeys.map(_ -> _.Id)
}
因此它 returns 键 -> ID 的映射。问题是 batchCacheable 只能将 CacheKey
的 Seq 传递给它,但我需要它是 ID 的 IDCacheKey
Seq。我该怎么做?
一个简单的解决方案是做这样的事情:
def getStringsFromLMS(cacheKeys: Seq[CacheKey]): Try[Map[CacheKey, String]] = {
cacheKeys.collect { case k: IDCacheKey => k.id }
}
这将默默地忽略所有不是 IDCacheKey
的内容。如果您宁愿在输入中存在错误类型的键时抛出错误,只需将 .collect
替换为 .map
.
无论如何,这都不是正确的解决方案。声明为 expect CacheKey
的函数应该能够处理 any CacheKey
的实例,无论是什么类型。
在更一般的层面上,没有提供足够的身份信息来获取值的 CacheKey
不是很有用。
长话短说,您的 CacheKey
特征似乎需要一个抽象的 id
方法。这将以自然(和“正确”)的方式解决您的问题。
或者,您可以进一步参数化 batchCacheable
:
def batchCacheable[T, K <: CacheKey](cacheKeys: Seq[K])(
callServiceToFetchValues: Seq[K] => Try[Map[K, T]]
): Try[Map[K, T]]
这让您声明 getStringsFromLMS
接受 IDCacheKey
,并且仍然可以与 batchCacheable