簡體   English   中英

Scala 案例類使用可序列化擴展產品

[英]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兩個特征,即ProductSerializable

Product trait 被擴展為case class是具有product type代數數據類型

Serializable trait 得到了擴展,因此case class可以被視為純數據 - 即能夠被序列化。

case class DogCat ,您的特征Animal不擴展ProductSerializable 因此,您看到的類型簽名。

當您聲明諸如Array(Dog(""), Cat("")) ,scalac 需要推斷可以表示給定數組所有元素的單一頂部類型

這就是為什么推斷的類型是Product with Serializable with Animal因為Animal沒有擴展ProductSerializablecase class隱式地做了。

要解決此推斷,您可以通過Animal使類型顯式,或使Animal擴展ProductSerializable

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 類都有一些屬性:

  1. 它們將自動擴展Product trait 並為它們提供默認實現,因為它們可以被視為N 條記錄的笛卡爾積
  2. 它們將擴展Serializable因為它們是開箱即用的(作為設計選擇)。
  3. 它們將具有編譯器提供的hashCodeequals的實現,這有助於模式匹配
  4. 它們將提供applyunapply方法,用於類型的組合和分解。

Case 類也是 Scala 表達代數數據類型,更具體地說是產品類型的方式 元組也是一種產品類型,因此它們也擴展了Product特性。

當您使用具有共同特征的兩個 case 類時,scala 的編譯器將使用它的類型推斷算法來嘗試找到ArrayT類型的最小上限 (LUB)。 由於這兩個 case 類都通過編譯器擴展了ProductSerializable ,而trait沒有,它會在搜索過程中將其應用到最終的計算類型。

如果你想避免看到這種情況,你可以讓你的 trait 顯式擴展這些 trait:

sealed trait Animal extends Product with Serializable

可以在此處找到有關此主題的更多信息

所有 case 類都會自動擴展ProductSerializable 長得難看? 是的。 基本上, Product可以被視為異構集合。 所有產品類別即。 (Product1 , Product2 ...) 擴展Product ,其中包含一些常用方法,如productArityproductElement等。

與 Case 類一樣,擴展Product其他類型是ListTuple

從我的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM