三元运算符类似于 ?:

发布于 2024-10-16 18:59:48 字数 1334 浏览 1 评论 0原文

我试图避免这样的构造:

val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result

好的,在这个例子中,thenelse 分支很简单,但你可以想象复杂的分支。 我构建了以下内容:

object TernaryOp {
  class Ternary[T](t: T) {
    def is[R](bte: BranchThenElse[T,R]) = if (bte.branch(t)) bte.then(t) else bte.elze(t)
  }
  class Branch[T](branch: T => Boolean) {
    def ?[R] (then: T => R) = new BranchThen(branch,then)
  }
  class BranchThen[T,R](val branch: T => Boolean, val then: T => R)
  class Elze[T,R](elze: T => R) {
    def :: (bt: BranchThen[T,R]) = new BranchThenElse(bt.branch,bt.then,elze)
  }
  class BranchThenElse[T,R](val branch: T => Boolean, val then: T => R, val elze: T => R)
  implicit def any2Ternary[T](t: T) = new Ternary(t)
  implicit def fct2Branch[T](branch: T => Boolean) = new Branch(branch)
  implicit def fct2Elze[T,R](elze: T => R) = new Elze(elze)
}

定义了这一点,我可以将上面的简单示例替换为:

this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}

但是如何摆脱 s: String =>?我想要这样的东西:

this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}

我想编译器需要额外的东西来推断类型。

I am trying to avoid constructs like this:

val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result

Ok, in this example the then and else branch are simple, but you can image complex ones.
I built the following:

object TernaryOp {
  class Ternary[T](t: T) {
    def is[R](bte: BranchThenElse[T,R]) = if (bte.branch(t)) bte.then(t) else bte.elze(t)
  }
  class Branch[T](branch: T => Boolean) {
    def ?[R] (then: T => R) = new BranchThen(branch,then)
  }
  class BranchThen[T,R](val branch: T => Boolean, val then: T => R)
  class Elze[T,R](elze: T => R) {
    def :: (bt: BranchThen[T,R]) = new BranchThenElse(bt.branch,bt.then,elze)
  }
  class BranchThenElse[T,R](val branch: T => Boolean, val then: T => R, val elze: T => R)
  implicit def any2Ternary[T](t: T) = new Ternary(t)
  implicit def fct2Branch[T](branch: T => Boolean) = new Branch(branch)
  implicit def fct2Elze[T,R](elze: T => R) = new Elze(elze)
}

Defined that, I can replace the above simple example with:

this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}

But how can I get rid of the s: String =>? I want something like that:

this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}

I guess the compiler needs the extra stuff to infer types.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

漫雪独思 2024-10-23 18:59:48

来自 Tony Morris 的 Lambda 博客

我经常听到这个问题。是的,确实如此。而不是 c ? p : q,就是
写成if(c) p else q

这可能不是更好的选择。也许您想使用
与Java 语法相同。可悲的是,你不能。这是因为 : 不是
有效的标识符。不要害怕,| 就是!你会接受这个吗?

<前><代码>c ? p| q

然后您将需要以下代码。注意按名称调用 (=>)
对参数的注释。该评估策略需要
正确重写Java的三元运算符。这在 Java 中无法完成
本身。

case class Bool(b: Boolean) {   
  def ?[X](t: => X) = 新 {
    def |(f: => X) = if(b) t else f   
  } 
}

对象布尔 {   
  隐式 def BooleanBool(b: 布尔值) = Bool(b) 
}

这是一个使用我们刚刚定义的 new 运算符的示例:

对象 T { val 条件 = true

  导入布尔值._

  // 耶!   
  val x = 条件 ? “是”| “不”
}

玩得开心;)

From Tony Morris' Lambda Blog:

I hear this question a lot. Yes it does. Instead of c ? p : q, it is
written if(c) p else q.

This may not be preferable. Perhaps you’d like to write it using the
same syntax as Java. Sadly, you can’t. This is because : is not a
valid identifier. Fear not, | is! Would you settle for this?

c ? p | q

Then you’ll need the following code. Notice the call-by-name (=>)
annotations on the arguments. This evaluation strategy is required to
correctly rewrite Java’s ternary operator. This cannot be done in Java
itself.

case class Bool(b: Boolean) {   
  def ?[X](t: => X) = new {
    def |(f: => X) = if(b) t else f   
  } 
}

object Bool {   
  implicit def BooleanBool(b: Boolean) = Bool(b) 
}

Here is an example using the new operator that we just defined:

object T {   val condition = true

  import Bool._

  // yay!   
  val x = condition ? "yes" | "no"
}

Have fun ;)

灼疼热情 2024-10-23 18:59:48

我们可以将 如何在 Scala 中定义保留前导标记的三元运算符?选项包装值是一个好的模式吗? 获取

scala>   "Hi".getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res0: String = String

scala> List.getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res1: String = List

这是否足以满足您的需求?

We can combine How to define a ternary operator in Scala which preserves leading tokens? with the answer to Is Option wrapping a value a good pattern? to get

scala>   "Hi".getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res0: String = String

scala> List.getClass.getSimpleName |> {x => x.endsWith("$") ? x.init | x}
res1: String = List

Is this adequate for your needs?

回梦 2024-10-23 18:59:48

Rex Kerr的答案用基本的Scala表达:

"Hi".getClass.getSimpleName match {
  case x if x.endsWith("$") => x.init
  case x => x
}

虽然我不确定哪一部分您想要优化的 if-else 结构。

Rex Kerr’s answer expressed in basic Scala:

"Hi".getClass.getSimpleName match {
  case x if x.endsWith("$") => x.init
  case x => x
}

although I’m not sure what part of the if–else construct you want to optimise.

第七度阳光i 2024-10-23 18:59:48

由于 Scala 中的 if-else 结构返回一个值,因此您可以使用此

val a = if (1 < 0) 1 else 2

更多信息: https://alvinalexander.com/scala/scala-if-then-ternary-operator-cookbook-examples

Since if-else constructions in Scala return a value, you can use this

val a = if (1 < 0) 1 else 2

More info: https://alvinalexander.com/scala/scala-if-then-ternary-operator-cookbook-examples

浅语花开 2024-10-23 18:59:48

由于 : 本身不是一个有效的运算符,除非您同意始终使用反引号 : 转义它,因此您可以使用另一个字符,例如“|”正如上面的答案之一。但是有山羊胡子的猫王怎么样?::

implicit class Question[T](predicate: => Boolean) {
  def ?(left: => T) = predicate -> left
}
implicit class Colon[R](right: => R) {
  def ::[L <% R](pair: (Boolean, L)): R = if (q._1) q._2 else right
}
val x = (5 % 2 == 0) ? 5 :: 4.5

当然,如果你的值是列表,这又不起作用,因为它们本身有 :: 运算符。

Since : by itself won't be a valid operator unless you are ok with always escaping it with back ticks :, you could go with another character, e.g. "|" as in one of the answers above. But how about elvis with a goatee ?::

implicit class Question[T](predicate: => Boolean) {
  def ?(left: => T) = predicate -> left
}
implicit class Colon[R](right: => R) {
  def ::[L <% R](pair: (Boolean, L)): R = if (q._1) q._2 else right
}
val x = (5 % 2 == 0) ? 5 :: 4.5

Of course this again won't work if you values are lists, since they have :: operator themselves.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文