3

Scalaには、さまざまなケースクラスに一致する関数がありますが、一致するたびに同じコードを実行します。「フォールスルー」する可能性はありますか?または、コードを複製せず、関数を定義せずに、以下のコードを記述する他の優れた方法はありますか?

symbol match {
            case Times(a,b) => //some code using a and b
            case Plus(a,b)  => //same code as above
            case Div(a,b)   => //again same code as above
}

これは、 「「フォールスルー」に一致する:複数のケースに対して同じコードを実行するか? 」という質問にも非常によく似ていますが、ケースクラスとの一致に重点を置いている点が異なります。

4

3 に答える 3

4

いいえ、フォールトラフは他の言語のバグの一般的な原因であるため、Scala では禁止されています。2 つの3 つの可能性があります。

  • 関数内で同一のものをすべて除外する
  • ワイルドカードを使用するなど、特定性の低いマッチングを使用してみてください。BinaryOperationあなたの例では、これは、より一般的な一致の可能性を与えるスーパークラスを導入することも意味します。ケース クラスの継承制限により、スーパー ケース クラスを使用する代わりに、このスーパークラスのフィールドの使用に依存する必要があることに注意してください。
  • 特定の抽出プログラムを作成するための Mirko Stocker の素晴らしい提案に従ってください。
于 2013-02-22T08:40:24.003 に答える
4

3 つのケースを組み合わせてタプルに変換する独自のエクストラクタを作成できます。

  object BinOp {
    def unapply(op: Op) = op match {
      case Times(a, b) => Some(a, b)
      case Plus(a, b) => Some(a, b)
      case Div(a, b) => Some(a, b)
    }
  }

  symbol match {
    case BinOp(a, b) => 
  }
于 2013-02-22T08:55:57.587 に答える
1

あなたの問題に対する2つの解決策が考えられます

1)unapply

M.ストッカーの答えを拡張すると、次のようにデータを整理できます。

trait Op

trait BinaryOp extends Op {
  def a: Int
  def b: Int
}

object BinaryOp {
  def unapply(op: Op) = op match {
    case x: BinaryOp => Some((x.a, x.b))
    case _ => None
  }
}

case class Times(a: Int, b: Int) extends BinaryOp
case class Plus(a: Int, b: Int) extends BinaryOp
case class Div(a: Int, b: Int) extends BinaryOp

使用法:

symbol match {
  case BinaryOp(a, b) => f(a, b)
  case _ => //...
}

2)Product

すべてのケース クラスはProduct トレイトを拡張します

これにより、次のマッチングを行うことができます。

symbol match {
  case p: Product if p.productArity == 2 => {
    val a = p.productElement(0) //this has type Any, so a cast may be necessary
    val b = p.productElement(1)
    f(a, b)
  }
}

2 番目のケースはより一般的ですが、型安全ではありません。最初の解決策をお勧めします。

于 2013-02-22T09:44:09.877 に答える