Scala中如何在Case Classes中使用Template Parameter实现类型约束
问题根源
你将StateResponse定义在带泛型参数的抽象类Test1[STATE]内部,属于Scala的路径依赖类型:内部类的类型绑定到抽象类的具体实例上,不同的Test1实例对应的StateResponse是完全独立的类型,既不属于顶层的Test1伴生对象,也不能直接通过Test1.StateResponse这种类名直接访问,因此你在全局做模式匹配时无法找到对应的类型。
推荐解决方案
最符合Scala语法规范、且业务适配性最高的方案是将泛型参数提升到顶层的Response trait和StateResponse样例类上,不要将样例类定义在抽象类内部:
// 伴生对象中定义带泛型的响应类型 object Test1 { sealed trait Response[+STATE] final case class StateResponse[STATE](state: STATE) extends Response[STATE] } // 抽象类直接使用带泛型的样例类即可 abstract class Test1[STATE] { def something(): Unit = { // 业务逻辑中直接使用 StateResponse[STATE] 类型,state自动为STATE类型,无需Any } }
使用时的模式匹配逻辑不需要做大改动,就能自动获得类型安全的state变量:
import Test1._ val result: Response[Test1State] = ??? result match { case StateResponse(state) => // 此处state自动为Test1State类型,无需类型转换 case _ => }
其他可选方案(不推荐)
如果你坚持要将样例类定义在抽象类内部,模式匹配时必须绑定到对应的Test1实例才能访问内部类:
val implInstance = new Test1Impl() // result必须是implInstance产生的响应对象 result match { case implInstance.StateResponse(state) => // state为Test1State类型 case _ => }
该方案要求匹配时必须持有生成响应的抽象类实例,适用场景非常有限。
内容的提问来源于stack exchange,提问作者posthumecaver
相关产品推荐
相关产品推荐

