我尝试使用抽象类型定义类型约束。但不幸的是,它没有编译。
sealed trait MatchableValue {
type A
def value: A
def asSingleItemValue : ItemValue
}
sealed trait ItemValue {
type A
def value: A
}
case class StringValue(value: String) extends ItemValue {type A = String}
case class StringMatchableValue(value: String) extends MatchableValue{
type A = String
override def asSingleItemValue = StringValue(value)
}
不幸的是,这个不起作用
def asSingleItemValue[B <: ItemValue](implicit ev: A =:= B#A) : B
类型约束的目的是在编译时警告这样的错误:
case class IntValue(value: Int) extends ItemValue {type A = Int}
case class IntMatchableValue(value: Int) extends MatchableValue{
type A = Int
def asSingleItemValue = StringValue("error")
}
答案 0 :(得分:5)
您可以使用类型细化来完成此操作(请注意方法的返回类型):
sealed trait MatchableValue { self =>
type A
def value: A
def asSingleItemValue: ItemValue { type A = self.A }
}
sealed trait ItemValue {
type A
def value: A
}
case class StringValue(value: String) extends ItemValue { type A = String }
case class IntValue(value: Int) extends ItemValue { type A = Int }
现在编译:
case class StringMatchableValue(value: String) extends MatchableValue {
type A = String
def asSingleItemValue = StringValue(value)
}
但这不是:
case class StringMatchableValue(value: String) extends MatchableValue {
type A = String
def asSingleItemValue = IntValue(1)
}
我认为这就是你想要的。
值得注意的是,在处理类型细化时,以下是一种常见模式:
sealed trait MatchableValue { self =>
type A
def value: A
def asSingleItemValue: ItemValue.Aux[A]
}
sealed trait ItemValue {
type A
def value: A
}
object ItemValue {
type Aux[A0] = ItemValue { type A = A0 }
}
这完全相同,但如果你发现自己需要大量写出类型细化,那么语法是一个不错的选择。
答案 1 :(得分:0)
我认为您打算在代码中删除此行?
def asSingleItemValue = StringValue(value)
并且override
定义缺少一些签名,应该是这样的:
override def asSingleItemValue[B <: ItemValue](implicit ev: =:=[String, B#A]): B = ev
最后,生成的ev
类型必须为B
。