[英]Scala case class extending Product with Serializable
我正在學習 Scala 並嘗試使用以下表格 Scala Cookbook:
trait Animal
trait FurryAnimal extends Animal
case class Dog(name:String) extends Animal
case class Cat(name:String) extends Animal
現在,當我執行以下操作時:
val x = Array(Dog("Fido"),Cat("Felix"))
結果顯示為:
x:Array[Product with Serializable with Animal] = Array(Dog(Fido),Cat(Felix))
雖然我知道案例類與產品特征混合在一起
我沒有得到的是: Product with Serializable with Animal
根據我的理解產品與模式匹配有關
我確實用谷歌搜索但沒有得到任何東西。請幫助我詳細了解這個概念。
謝謝
由於case class
工作方式,這是預期的行為。 case class
自動extends
兩個特征,即Product
和Serializable
。
Product
trait 被擴展為case class
是具有product type的代數數據類型。
Serializable
trait 得到了擴展,因此case class
可以被視為純數據 - 即能夠被序列化。
與case class
Dog
和Cat
,您的特征Animal
不擴展Product
或Serializable
。 因此,您看到的類型簽名。
當您聲明諸如Array(Dog(""), Cat(""))
,scalac 需要推斷可以表示給定數組所有元素的單一頂部類型。
這就是為什么推斷的類型是Product with Serializable with Animal
因為Animal
沒有擴展Product
也Serializable
而case class
隱式地做了。
要解決此推斷,您可以通過Animal
使類型顯式,或使Animal
擴展Product
和Serializable
。
trait Animal extends Product with Serializable
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal
Array(Dog(""), Cat("")) // Array[Animal] = Array(Dog(), Cat())
Scala 中的所有 case 類都有一些屬性:
Product
trait 並為它們提供默認實現,因為它們可以被視為N 條記錄的笛卡爾積。Serializable
因為它們是開箱即用的(作為設計選擇)。hashCode
和equals
的實現,這有助於模式匹配apply
和unapply
方法,用於類型的組合和分解。 Case 類也是 Scala 表達代數數據類型,更具體地說是產品類型的方式。 元組也是一種產品類型,因此它們也擴展了Product
特性。
當您使用具有共同特征的兩個 case 類時,scala 的編譯器將使用它的類型推斷算法來嘗試找到Array
的T
類型的最小上限 (LUB)。 由於這兩個 case 類都通過編譯器擴展了Product
和Serializable
,而trait
沒有,它會在搜索過程中將其應用到最終的計算類型。
如果你想避免看到這種情況,你可以讓你的 trait 顯式擴展這些 trait:
sealed trait Animal extends Product with Serializable
所有 case 類都會自動擴展Product
和Serializable
。 長得難看? 是的。 基本上, Product
可以被視為異構集合。 所有產品類別即。 (Product1 , Product2 ...) 擴展Product
,其中包含一些常用方法,如productArity
、 productElement
等。
與 Case 類一樣,擴展Product
其他類型是List
、 Tuple
等
從我的 Scala 工作表中,
val product : Product = (10,"String",3) //> product : Product = (10,String,3)
product.productArity //> res0: Int = 3
product.productElement(0) //> res1: Any = 10
product.productElement(1) //> res2: Any = String
product.productElement(2) //> res3: Any = 3
case class ProductCase(age:Int,name:String,ISBN:Int)
ProductCase(23,"som",5465473).productArity //> res4: Int = 3
詳情請看這里。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.