【问题标题】:Concise conditional operator in ScalaScala中的简洁条件运算符
【发布时间】:2016-11-08 07:09:18
【问题描述】:

让我演示一下我对条件运算符的期望:

import scalaz._
import Scalaz._
import util.Random

trait Card

class BigCard extends Card

class SmallCard extends Card

object Main extends App {
  def printCard(card: Card) {println(card.getClass.getSimpleName)}

  // Line bellow works fine, but I would prefer less verbose conditional operator (like ?: from JavaScript).
  (if (Random.nextBoolean) new BigCard else new SmallCard) |> printCard

  // I thought ScalaZ's ?| was meant to be an alternative to if. But following statement fails to compile. 
  (Random.nextBoolean ? new BigCard | new SmallCard) |> printCard
}

结果:

[error] xxx/Main.scala:15: type mismatch;
[error]  found   : SmallCard
[error]  required: BigCard
[error]   (Random.nextBoolean ? new BigCard | new SmallCard) |> printCard
[error]                                       ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed

ScalaZ 有什么替代品吗?|支持子类的运算符(不确定该术语,还是类型扩展)?

我正在寻找一个简洁的条件运算符(因此手动添加类型是不可能的,它最终会比if 更长更丑陋)。是否可以轻松添加(如没有自定义宏)或某些库是否提供此类运算符?

【问题讨论】:

    标签: scala scalaz


    【解决方案1】:

    是的,这很容易(implicit class 不能在顶层声明,将其放入 object 并导入其内容):

    class Cond[A](x: Boolean, value: => A) {
      def |[B >: A](other: => B) = if (x) value else other
    }
    
    implicit class CondOp(x: Boolean) {
      def ?[A](y: => A) = new Cond(x, y)
    }
    

    Scalaz 显然定义了def |(other: A)

    缺点(可能是 Scalaz 不这样做的原因)是它还可以编译不相关的类型,因为在 Scala any 中,两种类型都有一个共同的超类型:Random.nextBoolean ? 1 | ""。此外,对于x ? 1 | 1.0,您不会像if 那样扩大到Double;它返回AnyVal

    【讨论】:

    • 谢谢,没想到这么简单。我会测试它。我认为编译器警告过扩大到 Any/AnyVal/AnyRef。我会添加按名称调用,因此它的行为更像经典 if(不评估其他分支)。
    • 工作正常,谢谢:)。如果有人需要惰性版本(或完整示例),请查看 gist.github.com/mnn/3ef2e1bb67a93733a7d293c0fe7e10c2
    • “我认为编译器警告过扩大到 Any/AnyVal/AnyRef。”是的,在这种情况下你会收到一个警告(关于名字的好点,我会编辑答案)。
    猜你喜欢
    • 1970-01-01
    • 2022-08-21
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    相关资源
    最近更新 更多