0

次の一致警告が表示されます。

"一致は網羅的ではない可能性があります。次の入力では失敗します: Some((x: Abstract forSome x not in (A, B, C))) "

コード:

abstract class Abstract
case class A() extends Abstract
case class B() extends Abstract
case class C() extends Abstract

class matcher {
  def matcher(a: Option[Abstract]) = a match {
    case None      => true  
    case Some(A()) => false 
    case Some(B()) => false 
    case Some(C()) => false 
  }
}

ご参考までに、ここのケース クラスには引数がありませんが、私の実際のコードでは引数があります。Abstract答えが「プログラムのどこかに追加のサブクラスがあるかどうかをコンパイラが認識できない...」ではないことを願っています...

抽象クラスを封印することが唯一の解決策ですか? scala はあまり動的な言語ではないのに、コンパイル警告で言及されているグループが空のグループであることをコンパイラが認識しないのはなぜでしょうか?

4

1 に答える 1

1

これはおそらく理想的ではありませんが、Abstract を封印したくない場合には機能します。

abstract class Abstract
sealed abstract class SealedAbstract
case class A() extends SealedAbstract
case class B() extends SealedAbstract
case class C() extends SealedAbstract

class matcher {
    def matcher(a: Option[Abstract]) = a match {
        case None => true  
        case Some(thing) => matcher(thing)
    }
    def matcher(a: Abstract) = a match{
        case seal: SealedAbstract => matcher(seal)
        case _ => false
    }
    //this will be exhaustive
    def matcher(a: SealedAbstract) a match{
        case A() => false
        case B() => false
        case C() => false
    }
}

Abstract オブジェクトに対してロジックを実行するためのより優れた (そしてより保守/拡張可能な) 方法は、型クラスを使用することです。

abstract class Abstract
sealed abstract class SealedAbstract
case class A() extends SealedAbstract
case class B() extends SealedAbstract
case class C() extends SealedAbstract

trait PerformAction[Type <: Abstract]{def doSomething(in: Type): String}
implicit object SealedPerformAction extends PerformAction[SealedAbstract]{
    override def doSomething(sa: SealedAbstract): String = "It does."
}

class matcher {
    def doIfExists[Type <: Abstract](a: Option[Type])(implicit ev: PerformAction[Type]): String = a match{
        case None => ""
        case Some(thing) => ev.doSomething(thing)
    }
}

型クラスを使用すると、徹底的なパターン マッチングが得られ、ライブラリのユーザーが独自の Abstract を実装する場合、PerformAction を実装する必要があるため、ライブラリの外部で型の安全性が得られます。

于 2015-04-12T14:30:09.480 に答える