即使语法没有按照预期的顺序进行计算——它将条件绑定到第一个选项!——你可以像这样制作自己的三元运算符:
class IfTrue[A](b: => Boolean, t: => A) { def |(f: => A) = if (b) t else f }
class MakeIfTrue(b: => Boolean) { def ?[A](t: => A) = new IfTrue[A](b,t) }
implicit def autoMakeIfTrue(b: => Boolean) = new MakeIfTrue(b)
诀窍是解释?
为对象上的一种方法,该方法MakeIfTrue
将条件绑定到对象以在“真”情况下返回。结果IfTrue
对象现在使用该|
方法作为评估条件的请求,如果条件为真,则返回存储的真选项,如果条件为假,则返回刚刚传入的选项。
请注意,我使用了类似的东西,=> A
而不仅仅是A
--by-name 参数 -- 为了不评估表达式,除非它被实际使用。因此,您将只评估您实际需要的一侧(就像 if 语句一样)。
让我们看看它的实际效果:
scala> List(1,3,2).isEmpty ? "Empty" | "Nonempty"
res0: java.lang.String = Nonempty
scala> (4*4 > 14) ? true | false
res1: Boolean = true
scala> class Scream(s: String) { println(s.toUpperCase + "!!!!") }
defined class Scream
scala> true ? new Scream("true") | new Scream("false")
TRUE!!!!
res3: Scream = Scream@1ccbdf7
(PS 为避免与 Actor 库混淆?
,您可能应该将其称为其他名称|?
。)