【发布时间】:2021-11-17 18:52:41
【问题描述】:
我有一个通用函数,它需要 T 类型的 HasMoveCapability 隐式实例(type class 模式)
trait HasMoveCapability[T]
def doLogic[T: TypeTag: HasMoveCapability](): Unit = println(typeTag[T].tpe)
然后我有这两个具有 HasMoveCapability[T] 隐式实例的类
case class Bird()
object Bird {
implicit val hasMoveCapability = new HasMoveCapability[Bird]{}
}
case class Lion()
object Lion {
implicit val hasMoveCapability = new HasMoveCapability[Lion]{}
}
我的问题如下:
我需要根据参数在 runtime 解析类型(Lion 或 Bird),并使用正确的类型调用函数 doLogic。
我试过了
val input: String = "bird" // known at runtime
val resolvedType: TypeTag[_] = input match {
case "bird" => typeTag[Bird]
case "lion" => typeTag[Lion]
}
doLogic()(resolvedType) // doesn't compile
// `Unspecified value parameters: hasMoveCapability$T$1: HasMoveCapability[NotInferredT]`
我想做的是这样的:
val resolvedType: TypeTag[_: HasMoveCapability] = input match{...}
目前我使用的解决方法是在模式匹配中调用函数:
input match {
case "bird" => doLogic[Bird]
case "lion" => doLogic[Lion]
}
但是由于具有许多功能,模式匹配变得重复且难以维护。
如果您有任何建议,我愿意更改设计:D
【问题讨论】:
-
“但是由于具有许多功能,模式匹配变得重复且难以维护”。我个人宁愿尝试解决这个问题,也许创建一个类似
main的函数来做所有事情,这样你就只在模式匹配中调用一个?或者,也许您可以创建一个包含您需要的所有类型类的数据结构,然后从模式匹配中返回它。 -
感谢您的评论 1- 在我的情况下,创建一个我从模式匹配中调用的类似 main 的函数实际上是不可能的,我有许多 main-functions/jobs 用于需要的不同用例使用相同的模式匹配 2- 我虽然要返回所有类型类,但这也不理想,因为我的模式匹配中有很多条目,每次添加新的类型类时,我都需要更新所有条目的结构,而实例已经存在于相应的伴随对象中。
-
我会保持模式匹配然后,您需要将运行时值映射到编译时类型,而模式匹配是最简单/最自然的方法。如果并非所有案例都具有相同的逻辑,这似乎也是进行该匹配的一个很好的理由,并非所有重复都是不好的,在这种情况下,案例的重复似乎只会让您在未来进行更改的清晰性和简单性。
标签: scala functional-programming typeclass