trait Ingredient{}
case class Papperoni() extends Ingredient{}
case class Mushroom() extends Ingredient{}
trait ToppingDef[T] {
}
object PepperoniDef extends Serializable with ToppingDef[Papperoni] {
}
object MushroomDef extends Serializable with ToppingDef[Mushroom] {
}
class Oven[T <: Ingredient](val topping:ToppingDef[T]) {
}
class Pizza {
def cook = {
val topping =
if(someCondition()) { PepperoniDef }
else { MushroomDef}
new Oven(topping) // <-- build error here
}
}
私はScala 2.11を使用しています。この例は多少の工夫をしていますが、私は問題に無関係なものをすべて取り除いて、簡潔な例を提供しています。Scala:式の型が仮パラメータ型と互換性がありません
私は最後の行に乗るエラーは次のとおりです。
Error:(26, 5) no type parameters for constructor Oven: (topping: ToppingDef[T])Oven[T] exist so that it can be applied to arguments (Serializable with ToppingDef[_ >: Papperoni with Mushroom <: Product with Serializable with Ingredient])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : Serializable with ToppingDef[_ >: Papperoni with Mushroom <: Product with Serializable with Ingredient]
required: ToppingDef[?T]
new Oven(topping)
は、しかし、たとえばこれに最後の行を変更:
new Oven(PepperoniDef)
は罰金構築します。したがって、コンパイラは、パラメータが明示的にこのように渡されたときに型の検索に問題はありません。
また、このようPepperoniDef
とMushroomDef
からSerializable
形質を取り除く:
object PepperoniDef extends ToppingDef[Papperoni] {
}
object MushroomDef extends ToppingDef[Mushroom] {
}
も構築します。しかし私の場合、私はSerializableが必要です。
私はおそらく、これを回避するコードを必要に応じて再構成することができますが、何が起こっているのか理解したいと思います。なぜ型が最初のケースであいまいか、形質には何の効果もありません。あらゆる洞察に感謝します。
編集:非常に参考にしていただきありがとうございます。これに
val topping =
:私が最も簡潔な修正がこれを変更することだと思うビルドエラーが硬化し、私は維持したいと思いますジェネリッククラスへの変更を必要としない
val topping:ToppingDef[_ <: Ingredient] =
Scalaができるだけ多くの型情報を推論できるように、できるだけシンプルではない。
Serializable
の存在がこれに何らかの影響を与える理由についての質問には答えません。
本当の質問は、 (ToppingDef [_ <:Ingredient] 'で簡略化することができます)は、' T <:Ingredient'に対して 'ToppingDef [T]'を満たしていませんか? 'Topping'の型を' ToppingDef [_ <:Ingredient] 'に設定した場合、ToppingDef [_ <:Ingredient>'に設定すると同じエラーが発生します。なぜ...あなたはできますか? –
@TzachZoharスペックを見る。 –
@TzachZohar仕様には何も書かれていませんが、私は '-Ytyper-debug'出力を見ましたが、有益な情報は出ませんでした。バグのようなにおいがする。 –