如何在 Scala 中定义保留前导标记的三元运算符?

2023-11-21

我正在编写一个生成 Scala 输出的代码生成器。

我需要以这样的方式模拟三元运算符,即导致“?”的标记保持不变。

例如转换表达式c ? p : q to c something。简单的if(c) p else q不符合我的标准,因为它需要if( before c.

我的第一次尝试(仍然使用上面的 c/p/q )是



c match { case(true) => p; case _ => q }
  

我发现的另一个选择是:



class ternary(val g: Boolean => Any) { def |: (b:Boolean) = g(b) }

implicit def autoTernary (g: Boolean => Any): ternary = new ternary(g)
  

这让我可以写:



c |: { b: Boolean => if(b) p else q }
  

我喜欢第二个选项的整体外观,但是有没有办法让它不那么冗长?

Thanks


即使语法没有按照预期的顺序求值——它将条件绑定到第一个选项!——你也可以像这样创建自己的三元运算符:

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将条件绑定到要在“true”情况下返回的对象的对象。所结果的IfTrue对象现在使用|方法作为评估条件的请求,如果条件为 true,则返回存储的 true 选项,如果条件为 false,则返回刚刚传入的选项。

请注意,我用过类似的东西=> 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

(P.S.为了避免与 Actor 库混淆?,你可能应该将其称为其他名称,例如|?.)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Scala 中定义保留前导标记的三元运算符? 的相关文章

随机推荐