scala 类似于 ? 的三元运算符:
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4947535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ternary Operator Similar To ?:
提问by Peter Schmitz
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 thenand elsebranch are simple, but you can image complex ones.
I built the following:
好的,在这个例子中,then和else分支很简单,但你可以想象复杂的。我构建了以下内容:
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:
但是我怎样才能摆脱s: String =>?我想要这样的东西:
this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}
I guess the compiler needs the extra stuff to infer types.
我猜编译器需要额外的东西来推断类型。
采纳答案by Rex Kerr
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 中定义一个保留前导标记的三元运算符?答案是 Option wrapping a value a good pattern? 要得到
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?
这是否足以满足您的需求?
回答by Landei
From Tony Morris' Lambda Blog:
I hear this question a lot. Yes it does. Instead of
c ? p : q, it is writtenif(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 | qThen 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 ;)
我经常听到这个问题。是的,它确实。相反
c ? p : q,它被写入if(c) p else q。这可能不是优选的。也许您想使用与 Java 相同的语法来编写它。可悲的是,你不能。这是因为
:不是有效的标识符。不要害怕,|是!你愿意接受这个吗?c ? p | q然后你需要下面的代码。注意参数上的 call-by-name (
=>) 注释。要正确重写 Java 的三元运算符,需要此评估策略。这不能在 Java 本身中完成。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) }这是一个使用我们刚刚定义的 new 运算符的示例:
object T { val condition = true import Bool._ // yay! val x = condition ? "yes" | "no" }玩得开心 ;)
回答by Debilski
Rex Kerr's answerexpressed 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.
虽然我不确定您想要优化 if-else 结构的哪一部分。
回答by Wouter
Since if-else constructions in Scala return a value, you can use this
由于 Scala 中的 if-else 构造返回一个值,因此您可以使用它
val a = if (1 < 0) 1 else 2
More info: https://alvinalexander.com/scala/scala-if-then-ternary-operator-cookbook-examples
更多信息:https: //alvinalexander.com/scala/scala-if-then-ternary-operator-cookbook-examples
回答by Ustaman Sangat
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.
当然,如果您的值是列表,这将再次不起作用,因为它们本身具有 :: 运算符。

