三元运算符类似于?:

Pet*_*itz 88 scala

我试图避免像这样的结构:

val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result
Run Code Online (Sandbox Code Playgroud)

好吧,在这个例子中,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)
}
Run Code Online (Sandbox Code Playgroud)

定义一下,我可以用以下代码替换上面的简单示例:

this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}
Run Code Online (Sandbox Code Playgroud)

但我怎么能摆脱s: String =>?我想要这样的东西:

this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}
Run Code Online (Sandbox Code Playgroud)

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

Lan*_*dei 121

来自Tony Morris的Lambda博客:

我经常听到这个问题.是的,它确实.而不是c ? p : q,它是写的if(c) p else q.

这可能不是优选的.也许您想使用与Java相同的语法编写它.可悲的是,你做不到.这是因为:它不是有效的标识符.不要害怕,|是!你会满足于此吗?

c ? p | q
Run Code Online (Sandbox Code Playgroud)

然后你需要以下代码.注意参数上的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) 
}
Run Code Online (Sandbox Code Playgroud)

以下是使用我们刚刚定义的new运算符的示例:

object T {   val condition = true

  import Bool._

  // yay!   
  val x = condition ? "yes" | "no"
}
Run Code Online (Sandbox Code Playgroud)

玩得开心 ;)

  • 我采用了'if(c)p else q`方法......缺少括号让我感觉不舒服但这只是一种风格的东西 (4认同)

Rex*_*err 26

我们可以结合如何在Scala中定义一个三元运算符来保留前导令牌?回答Is Option包装一个好的模式吗?要得到

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
Run Code Online (Sandbox Code Playgroud)

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


Deb*_*ski 16

Rex Kerr在基本Scala中表达的答案:

"Hi".getClass.getSimpleName match {
  case x if x.endsWith("$") => x.init
  case x => x
}
Run Code Online (Sandbox Code Playgroud)

虽然我不确定你想要优化的if-else结构的哪个部分.


Wou*_*ter 7

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

val a = if (1 < 0) 1 else 2
Run Code Online (Sandbox Code Playgroud)

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