*因爲我們知道scala數組包含相同類型的數據。但是當我聲明數組爲具有不同數據類型的Scala數組
var a = new Array[Any](3)
我能夠存儲不同的數據類型。
a(0)=5
a(1)="hello"
a(2)=1.5
怎麼可能?如果它是錯誤的,那麼我們在scala中有什麼選擇來存儲不同的數據類型?*
*因爲我們知道scala數組包含相同類型的數據。但是當我聲明數組爲具有不同數據類型的Scala數組
var a = new Array[Any](3)
我能夠存儲不同的數據類型。
a(0)=5
a(1)="hello"
a(2)=1.5
怎麼可能?如果它是錯誤的,那麼我們在scala中有什麼選擇來存儲不同的數據類型?*
「相同類型」的概念總是取決於一般性級別。在Scala中,通用性的級別由正式類型決定。
3和7「同一類型」?如果我們寫...
val a : Int = 3
val b : Int = 7
然後他們的相同類型Int
。但是,如果我們定義位長度的限制Int
類型(我們是非常歡迎的斯卡拉做的),我們可以寫
val a : Int2 = 3
val b : Int3 = 7
,他們似乎不再是同一類型的!
如果我們定義一個繼承層次
trait Animal;
class Dog extends Animal;
class Frog extends Animal;
然後做Dog
和Frog
具有相同類型的?如果我們寫
val d : Dog = new Dog
val f : Frog = new Frog
那麼它看起來像答案是否定的。但如果我們寫
val d : Animal = new Dog
val f : Animal = new Frog
然後他們看起來像他們有相同的類型。與一致的,如果我聲明一樣
val arr : Array[Dog] = Array.ofDim[Dog](5)
一個數組,那麼我不能把一隻青蛙,因爲青蛙是不是狗。但是,如果我宣佈了類似的陣列
val arr : Array[Animal] = Array.ofDim[Animal](5)
那當然既青蛙和狗可以在裏面去,因爲在Animal
一般性的水平,無論是青蛙和狗都具有相同的類型。
在斯卡拉Any
是所有其他類型派生的基本類型。因此,在通用性水平非常高的情況下,5
,"hello"
和1.5
都具有相同類型Any
,就像通常的高級別Frog
和Dog
具有相同類型Animal
一樣。所以將5
,"hello"
和1.5
放入Array[Any]
是沒有問題的。
是的,你是對的scala array
,你確實存儲在這裏的數據same type
。看到這個例子:
scala> val a = Array(5,"hello",1.5)
a: Array[Any] = Array(5, hello, 1.5)
我們沒有看到包含integer
,string
和double
數組被創建。我們看到創建了一個array of Any
。在array creation
期間,scala編譯器尋找nearest common supertype in hierarchy
來滿足Array的屬性,它可以是hold elements of same type only
。在這種情況下,Any
是所有類的超類型,滿足條件。而且,如果編譯器找不到公共超類型,則數組創建將失敗。
需要注意的是,它不只是爲陣,這同樣適用於存儲其他collections
same types
。對於如:列出
scala> val list = List(5,"hello",1.5)
list: List[Any] = List(5, hello, 1.5)
什麼是我們在斯卡拉的選項來存儲不同類型的數據?
正如您所看到的,我們無法在List
和Array
這裏同時使用preserve the type of elements
。所有的元素都被存儲爲Any
。對於保留類型的元素,並將它們存儲起來,斯卡拉爲我們提供了Tuple
:
scala> val tuple = (5,"hello",1.5)
tuple: (Int, String, Double) = (5,hello,1.5)
正如其他人回答爲什麼Array[Any]
可以有類型的字符串,布爾值,詮釋等等元素讓我回答這個問題的下方部分
如果是錯誤的,那麼什麼是我們必須在Scala中存儲 不同的數據類型的選項?*
最明顯的答案是Shapeless library。 Shapeless支持稱爲HList
的高級數據結構,使用它可以將不同類型的類型存儲在列表中,而不會丟失類型信息。
例如參見下面的代碼段
scala> import shapeless.{::, HList, HNil}
import shapeless.{$colon$colon, HList, HNil}
scala> val list = 1 :: "a" :: true :: HNil
list: shapeless.::[Int,shapeless.::[String,shapeless.::[Boolean,shapeless.HNil]]] = 1 :: a :: true :: HNil
scala> list.head
res0: Int = 1 // notice the type of the element is Int and not Any
scala> list.tail.head
res1: String = a
scala> list.tail.tail.head
res2: Boolean = true
在上面的代碼你有HList
類型的不同的地址類型Int
,String
和Boolean
三個元件一個VAL list
。當您檢索HList
的元素時,元素的原始類型將被保留,並且您不會像Array的情況那樣獲得像Any
這樣的通用類型。這是可能的,因爲HList
不僅存儲數據,而且還存儲元素的類型信息,並在檢索時正確地轉換它們。
我認爲這個問題的正確答案太廣泛了。請參閱衆多Scala教程之一 –
您的問題表明您將價值理解爲只有一種獨特的類型。但它不會 - 在使用子類型的語言中,值可以同時成爲多種類型的成員。 –