Scala 三元运算符类似于?:
我试图避免这样的构造:Scala 三元运算符类似于?:,scala,Scala,我试图避免这样的构造: val result = this.getClass.getSimpleName if (result.endsWith("$")) result.init else result 好的,在本例中,then和else分支很简单,但您可以想象复杂的分支。 我构建了以下内容: object TernaryOp { class Ternary[T](t: T) { def is[R](bte: BranchThenElse[T,R]) = if (bte.bran
val result = this.getClass.getSimpleName
if (result.endsWith("$")) result.init else result
好的,在本例中,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)
}
定义为,我可以将上述简单示例替换为:
this.getClass.getSimpleName is {s: String => s.endsWith("$")} ? {s: String => s.init} :: {s: String => s}
但是我怎样才能摆脱s:String=>
?我想要这样的东西:
this.getClass.getSimpleName is {_.endsWith("$")} ? {_.init} :: {identity}
我想编译器需要额外的东西来推断类型。我们可以结合答案来得到
这是否足以满足您的需要?用基本Scala表示:
"Hi".getClass.getSimpleName match {
case x if x.endsWith("$") => x.init
case x => x
}
尽管我不确定您要优化if–else结构的哪一部分。来自:
我经常听到这个问题。是的。而不是c?p:q
,它是
写如果(c)p else q
这可能并不可取。也许你想用
语法与Java相同。遗憾的是,你不能。这是因为:
不是
有效标识符。不要害怕,|
是!你能接受这个吗
c ? p | q
然后您将需要以下代码。注意按名称调用(=>
)
关于参数的注释。这一评估战略需要:
正确重写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)
}
下面是一个使用我们刚刚定义的新运算符的示例:
object T { val condition = true
import Bool._
// yay!
val x = condition ? "yes" | "no"
}
玩得开心;)
因为:本身不是有效的运算符,除非您同意始终使用反勾号转义它
:
,您可以使用另一个字符,例如上面的一个答案中的“|”。那留着山羊胡子的猫王呢
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
隐式类问题[T](谓词:=>Boolean){
定义?(左:=>T)=谓词->左
}
隐式类冒号[R](右:=>R){
def::[L因为如果Scala中的else构造返回一个值,那么您可以使用
val a = if (1 < 0) 1 else 2
vala=if(1<0)1 else 2
更多信息:因为我的回答中没有这个问题——你遇到问题的原因是类型推断从左到右最有效,但是你要从右到左将你的标记绑定在一起,因为操作符的优先级。如果你把所有的语句都写在单词上(具有相同的优先级)并改变事物组合的方式,您将得到您想要的推论。(即,您将拥有HasIs
,IsWithCondition
,condition和truecase
类,这些类将从左到右构建表达式的一部分。)我无意识地假定了从左到右的类型推断方式,但却对方法名的运算符优先级和关联性感到困惑,特别是在任何其他alphanum字符之前以?
开头作为方法名的第一个字符,以:
作为左关联性。因此,我必须重新思考新的方法名以获得类型推断从左到右工作。谢谢!是的,我以前见过这个,但区别是,a我在然后和else
子句中将我的第一个表达式的(计算)值作为参数p else q
approach…缺少大括号让我有点不舒服,但这只是一种很直接的风格。有时人们会忘记日常使用的match/case语句。我只是坚持使用一行三元if-then else
习惯用法,但这确实是一种易懂的解决方法。模式匹配很容易扩展到更多的t韩:两个分支。这与我的想法非常接近。很好的方法。我会考虑一下。我避免使用第一个代码的原因是为了更简洁,在下面的if
-语句中没有一个临时val
:在一行中做到易懂,就像一个人记住它一样。
val a = if (1 < 0) 1 else 2