是的,您可以使用隐式和自定义运算符来模拟这一点。这是一个简短的例子:
implicit class FloatWrapper(n:Float) {
def :<(that:Float) = ResultAndLastItem(n<that, that)
def :>(that:Float) = ResultAndLastItem(n>that, that)
def :=(that:Float) = ResultAndLastItem(n==that, that)
// insert more comparison operations here
}
case class ResultAndLastItem(result:Boolean, lastItem:Float) extends FloatWrapper(lastItem) {
// insert boolean operations here
// boolean operations should return another instance of ResultAndLastItem (?)
}
implicit def toBoolean(r:ResultAndLastItem):Boolean = r.result
这是 REPL 中的示例用法:
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_45).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :paste
// Entering paste mode (ctrl-D to finish)
implicit class FloatWrapper(n:Float) {
def :<(that:Float) = ResultAndLastItem(n<that, that)
def :>(that:Float) = ResultAndLastItem(n>that, that)
def :=(that:Float) = ResultAndLastItem(n==that, that)
// insert more comparison operations here
}
case class ResultAndLastItem(result:Boolean, lastItem:Float) extends FloatWrapper(lastItem) {
// insert boolean operations here
// boolean operations should return another instance of ResultAndLastItem (?)
}
implicit def toBoolean(r:ResultAndLastItem):Boolean = r.result
// Exiting paste mode, now interpreting.
warning: there were 1 feature warnings; re-run with -feature for details
defined class FloatWrapper
defined class ResultAndLastItem
toBoolean: (r: ResultAndLastItem)Boolean
scala> if(2 :< 3 :< 4) "yay" else "nope"
res0: String = yay
scala> if(2 :< 3 :< 3) "nope" else "yay"
res1: String = yay
评论:
您可以轻松添加更多比较运算符,例如:<=
.
需要使用自定义运算符,因为这会强制编译器使用implicit class
上述运算符,而不是 s 的内置默认运算符Float
。
很难让我的示例更通用,以便允许所有可比较的类型,例如Double
、Int
或自定义类型。这很难的原因是因为implicit class FloatWrapper
不能需要进一步的implicit
参数 - 不能嵌套隐式。(或者更准确地说,它们可以在语法上,但是编译器不会选择它们进行隐式解析。)
作为一种优化,您可能需要考虑添加布尔快捷方式,即当已知表达式为 时false
,无需评估剩余的比较。
- 当您还添加布尔运算符(例如
||
or )时,这变得很棘手&&
。