3

私はscalaジェネリックで迷っています。

storeUnitのサブクラスのインスタンス (eq )を受け取り、 のサブクラスのUnitインスタンス (eq Visit) を返すメソッドが必要ですが、コンパイル エラーが発生します。StoredUnitStoredVisit

trait StatsUnit { val ip: String } 
case class Visit(ip: String) extends StatsUnit
case class Click(ip: String) extends StatsUnit

trait StoredStatsUnit extends StatsUnit { val id: String }
case class StoredVisit(id: String, ip: String) extends StoredStatsUnit
case class StoredClick(id: String, ip: String) extends StoredStatsUnit

def storeUnit[A <: StatsUnit, B <: StoredStatsUnit](statsUnit: A): B = {
  statsUnit match {
    case x: Visit => StoredVisit("myid", x.ip)
    case x: Click => StoredClick("myid", x.ip)
  }
}

/tmp/1.scala:11: error: type mismatch;
 found   : this.StoredVisit
 required: B
    case x: Visit => StoredVisit("myid", x.ip)
                                    ^
/tmp/1.scala:12: error: type mismatch;
 found   : this.StoredClick
 required: B
    case x: Click => StoredClick("myid", x.ip)
4

3 に答える 3

3

最初にコメント:

  1. あなたの特性に名前を付けないでくださいUnitUnitScala では特定の意味を持ちます (これは Java のものと同等です) void。その定義をシャドウイングしても問題が発生するだけです!

ただし、ここでの問題は、メソッドが のインスタンスを返すように指定してBから、 type の何かを返そうとすることですStoredVisit。この例ではまったく必要ないBため、次のようにするとうまくいきます。

def storeUnit[A <: StatsUnit](unit: A): StoredStatsUnit = {
  StoredVisit("myid", unit.ip)
}
于 2013-02-07T16:12:56.680 に答える
3

コードをコンパイルさせるためにコンパイラーに嘘をつきましょう。初め:

scala> def storeUnit[A <: StatsUnit, B <: StoredStatsUnit](unit: A): B = {
     |   StoredVisit("myid", unit.ip).asInstanceOf[B]
     | }
storeUnit: [A <: StatsUnit, B <: StoredStatsUnit](unit: A)B

の別のサブクラスを作成しましょうStoredStatsUnit:

case class UnStoredVisit(id: String, ip: String, n: Int) extends StoredStatsUnit

それでは、コンパイラがそのメソッド定義について不平を言っている理由を示しましょう。

scala> val visit: UnStoredVisit = storeUnit(Visit("1.2.3.4"))
java.lang.ClassCastException: StoredVisit cannot be cast to UnStoredVisit

つまり、の任意のサブクラスであるパラメータ化された B を返していませんStoredStatsUnit。を返してStoredVisitいます。これは、その特定のサブクラスの 1 つです。

于 2013-02-07T17:29:54.360 に答える
1

Bは のサブタイプでStoredUnitあり、StoredVisitは のサブタイプですが、と互換性StoredUnitのある有効な推論はありません。StoredVisitB

于 2013-02-07T16:14:44.567 に答える