Scala中如何在变量声明时使用抽象类型实现与类型参数等价效果
问题原因
Scala 编译器在推断 List 元素类型时,默认只会取元素最通用的父类型Transformer,不会自动保留每个 Transformer 实现里Input、Output的抽象类型细化信息,因此你声明的返回类型是带类型细化的List[Transformer {type Input = TransformerCollectionInput; type Output = TransformerCollectionOutput}],但编译器推断出来的实际返回值是List[Transformer],就出现了类型不匹配错误。
解决方案
你可以通过显式保留类型细化信息实现和类型参数版本完全一致的效果,添加辅助类型别名可以简化后续代码编写:
完整可运行修改版代码
trait Transformer { type Input type Output def transform(input: Input): Output } // 新增Aux类型别名,用来快速表示带固定Input/Output类型的Transformer,可选,仅用于简化代码 object Transformer { type Aux[I, O] = Transformer { type Input = I; type Output = O } } trait TransformerCollection { type TransformerCollectionInput type TransformerCollectionOutput // 此处也可以直接写你原来的完整细化类型,效果和用Aux别名完全一致 def transformers: List[Transformer.Aux[TransformerCollectionInput, TransformerCollectionOutput]] } object Int2StringTransformer extends Transformer { type Input = Int type Output = String def transform(input: Int): String = s"${input}" } object TwiceInt2StringTransformer extends Transformer { type Input = Int type Output = String def transform(input: Int): String = s"${2*input}" } object String2StringTransformer extends Transformer { type Input = String type Output = String def transform(input: String): String = s"${input}" } object TwiceString2StringTransformer extends Transformer { type Input = String type Output = String def transform(input: String): String = s"${input}${input}" } object Int2StringTransformerCollection extends TransformerCollection { type TransformerCollectionInput = Int type TransformerCollectionOutput = String // 核心修改:显式声明返回类型,引导编译器保留类型细化信息 override def transformers: List[Transformer.Aux[Int, String]] = List( Int2StringTransformer, TwiceInt2StringTransformer ) }
修改完成后,如果你尝试把String2StringTransformer加入上面的transformers列表,同样会触发编译错误,和类型参数版本的行为完全一致。如果你不想加Aux类型别名,直接把返回值类型写为List[Transformer {type Input = Int; type Output = String}]也可以得到完全相同的效果。
内容的提问来源于stack exchange,提问作者asds_asds
相关产品推荐
相关产品推荐

