为什么类型会导致“带有动物可序列化的产品”而不是动物?

Sri*_*vas 3 types scala

假设我有

val flag = true
Run Code Online (Sandbox Code Playgroud)

为什么会导致类型Product with Serializable with Animal而不只是类型Animal

class Animal(name : String)
case class Herbivore(name : String) extends Animal(name)
case class Carnivore(name : String) extends Animal(name)

val cow = new Herbivore("cow")
val tiger = new Carnivore("tiger")

if (flag) cow else tiger // Why is type Product with Serializable with Animal? 
Run Code Online (Sandbox Code Playgroud)

Mar*_*lic 7

案例类自动扩展, Product with Serializable因此

class Animal(name : String)
case class Herbivore(name : String) extends Animal(name)
case class Carnivore(name : String) extends Animal(name)
Run Code Online (Sandbox Code Playgroud)

实际上是

class Animal(name : String)
case class Herbivore(name : String) extends Animal(name) with Product with Serializable
case class Carnivore(name : String) extends Animal(name) with Product with Serializable
Run Code Online (Sandbox Code Playgroud)

因此,if (flag) cow else tiger编译器可以推断出的最精确的表达式类型是Product with Serializable with Animal。如果我们从案例类更改为像这样的类

class Animal(name : String)
class Herbivore(name : String) extends Animal(name)
class Carnivore(name : String) extends Animal(name)
Run Code Online (Sandbox Code Playgroud)

那么if-else表达式的推断类型确实是Animal

按照@TravisBrown的建议,使ADT根目录Product with Serializable像这样扩展

abstract class Animal(name : String) extends Product with Serializable
case class Herbivore(name : String) extends Animal(name)
case class Carnivore(name : String) extends Animal(name)
Run Code Online (Sandbox Code Playgroud)

也会使if-else表达式的推断类型也变为Animal