让我说我有:
sealed trait Data
final case class TextData() extends Data
final case class ImageData() extends Data
final case class MetaData[D <: Data](data: D) extends Data
我想模式匹配Data对象。我已定义:
def getDataTypeName(data: Data): String ={
data match {
case TextData()=>"text"
case ImageData()=>"image"
//MetaData(MetaData(_))=>"metaMeta1" //a
case _:MetaData[MetaData[_]]=>"metaMeta2" //b
//case MetaData(data:Data)=>"meta"+ getDataTypeName(data) //c
//MetaData(TextData(_))=>"metaMeta1" //d
case MetaData(_)=>"meta"
}
}
我希望能够看到我的数据是元元数据,元文本数据等。
第a
行给我一个错误,说:
构造函数无法实例化为期望的类型;发现: inst $ A $ A.MetaData [D]必需:A $ A115.this.Data案例 元数据(metadata(_))=&GT;&#34; metaMeta1&#34;
我更喜欢有类似行a
的东西。或者像c
这样的东西也会很好。
我也试过了行b
。这个会产生一些警告:
非变量类型参数A $ A115.this.MetaData [] in 类型模式A $ A115.this.MetaData [A $ A115.this.MetaData []]是 因为擦除而被删除,所以不加以控制 case :MetaData [MetaData []] =&gt;&#34; metaMeta&#34; ^
我收到了MetaData[_]s
的警告。我的理解是,在类型擦除后,所述模式减少到_,这与我的测试结果一致。
因此,我想知道是否有一种方法可以与MetaMetaData
,MetaTextData
,MetaMetaMetaData
等进行匹配。
或者,我的设计是否以不应该使用的方式使用密封类?你会建议什么样的替代设计?
答案 0 :(得分:3)
我对MetaData()
定义进行了更改,以使其发挥作用。
sealed trait Data
final case class TextData() extends Data
final case class ImageData() extends Data
final case class MetaData(data: Data) extends Data
def printType(data: Data): String = data match {
case TextData()=>"text"
case ImageData()=>"image"
case MetaData(d)=>"meta:" + printType(d)
}
val md = MetaData( MetaData(TextData()) )
printType(md) // res0: String = meta:meta:text
答案 1 :(得分:0)
sealed trait Data
final case class TextData() extends Data
final case class ImageData() extends Data
final case class MetaData[D <: Data](data: D) extends Data
和
def getDataTypeName(data: Data): String ={
data match {
case TextData()=>"text"
case ImageData()=>"image"
case MetaData(MetaData(_))=> "metaMeta1"
case MetaData(TextData())=> "textMeta1"
case MetaData(ImageData())=> "imgMeta1"
}
}
在REPL上进行测试:
scala> getDataTypeName(TextData())
res1: String = text
scala> getDataTypeName(MetaData(TextData()))
res2: String = textMeta1
scala> getDataTypeName(MetaData(MetaData(TextData())))
res3: String = metaMeta1