【发布时间】:2020-09-26 12:25:18
【问题描述】:
对于这个含糊不清或可能不正确的问题,我很抱歉,但我什至不知道如何用一句话来表达我的问题。
我有两个特点:
trait Property[T] {
val name: String
def conformsTo(rule: Rule[T]): Boolean
}
和
trait Rule[T] {
def evaluate(valueToCheck: T): Boolean
}
我有一个实现Property 的具体类的列表和一个Rule 实现的映射,其中两个参数化类型都可以是Double 或String。
遍历此列表时,对于每个 Property 实例,我将具体的 Rule 实现传递给 conformsTo 方法,但是编译器会出现类型不匹配的错误。
所以从更广泛的意义上说,我想要实现的是拥有一个属性列表,可以根据一组给定的不同类型的规则进行评估,而不是将这些属性按类型拆分为单独的列表。
我尝试修改上限/下限和隐式类型,但最终一无所获。
完整代码:
trait Rule[T] {
def evaluate(valueToCheck: T): Boolean
}
case class GreaterThan(value: Double) extends Rule[Double] {
override def evaluate(valueToCheck: Double): Boolean = {
valueToCheck > this.value
}
}
case class LessThan(value: Double) extends Rule[Double] {
override def evaluate(valueToCheck: Double): Boolean = {
valueToCheck < this.value
}
}
case class Is(value: String) extends Rule[String] {
override def evaluate(valueToCheck: String): Boolean = {
valueToCheck == this.value
}
}
case class isNot(value: String) extends Rule[String] {
override def evaluate(valueToCheck: String): Boolean = {
valueToCheck != this.value
}
}
trait Property[T] {
val name: String
def conformsTo(rule: Rule[T]): Boolean
}
case class DoubleProperty(name: String, value: Double) extends Property[Double] {
override def conformsTo(rule: Rule[Double]): Boolean = rule.evaluate(value)
}
case class StringProperty(name: String, value: String) extends Property[String] {
override def conformsTo(rule: Rule[String]): Boolean = rule.evaluate(value)
}
object Evaluator extends App {
val ruleMap = Map(
"name1" -> GreaterThan(123),
"name1" -> LessThan(500),
"name2" -> GreaterThan(1000),
"name3" -> Is("something"))
val numericProperty = DoubleProperty("name1", 600)
val numericProperty2 = DoubleProperty("name2", 1000)
val stringProperty = StringProperty("name3", "something")
val stringProperty2 = StringProperty("name4", "something")
val attributes = List(
numericProperty,
numericProperty2,
stringProperty,
stringProperty2)
val nonConforming = attributes
.filter(x => ruleMap.contains(x.name))
.filter(x => !x.conformsTo(ruleMap(x.name))).toList
}
错误:
type mismatch;
found : Product with Rule[_ >: String with Double] with java.io.Serializable
required: Rule[(some other)<root>._1]
Note: Any >: _1 (and Product with Rule[_ >: String with Double] with java.io.Serializable <: Rule[_ >: String with Double]), but trait Rule is invariant in type T.
You may wish to define T as -T instead. (SLS 4.5)
.filter(x => !x.conformsTo(ruleMap(x.name))).toList
感谢您的帮助。
【问题讨论】: