Scala数组具有不同的数据类型

时间:2017-02-05 07:58:56

标签: arrays scala any

*我们知道scala数组包含相同类型的数据。但是当我将数组声明为

var a = new Array[Any](3)

我可以存储不同的数据类型。

a(0)=5
a(1)="hello"
a(2)=1.5

怎么可能?如果它是错的那么我们在scala中有什么选项来存储不同的数据类型?*

3 个答案:

答案 0 :(得分:5)

“相同类型”的概念总是取决于一般性。在Scala中,一般性的级别由正式类型决定。

3和7“是同一类型”吗?如果我们写...

val a : Int = 3
val b : Int = 7

然后它们属于同一类型Int。但是,如果我们定义了位长限制Int类型(我们非常欢迎在Scala中这样做),我们可能会写

val a : Int2 = 3
val b : Int3 = 7

它们似乎不再是同一类型!

如果我们定义继承层次结构

trait Animal;
class Dog extends Animal;
class Frog extends Animal;

那么DogFrog具有相同的类型吗?如果我们写

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的普遍性水平上,青蛙和狗都有相同的类型。

在Scala中Any是一种基本类型,所有其他类型都是从中派生的。因此,在非常高的一般性,5"hello"1.5,所有类型Any具有相同的类型,就像在一般性的高级Frog一样Dog 1}}和Animal具有相同的类型5。因此,将"hello"1.5Array[Any]放入routes.php $route['default_controller'] = 'home'; $route['404_override'] = ''; $route['admin'] = 'admin/index'; 是没有问题的。

答案 1 :(得分:1)

是的,您对scala array是正确的,并且您确实存储了same type的数据。见这个例子:

scala> val a = Array(5,"hello",1.5)
a: Array[Any] = Array(5, hello, 1.5)

我们没有看到包含integerstringdouble的数组。我们看到创建了array of Any。在array creation期间,scala编译器查找nearest common supertype in hierarchy以满足它可以hold elements of same type only的Array属性。在这种情况下,Any是所有类的超类型,满足条件。而且,如果编译器无法找到常见的超类型,则阵列创建将失败。

请注意,它不仅适用于数组,也适用于存储collections的其他same types。例如:List

scala> val list = List(5,"hello",1.5)
list: List[Any] = List(5, hello, 1.5)

scala存储不同数据类型的选项是什么?

您可以看到我们preserve the type of elementsList无法Array。所有元素都存储为Any。为了保留元素类型并将它们存储在一起,scala为我们提供了Tuple

scala> val tuple = (5,"hello",1.5)
tuple: (Int, String, Double) = (5,hello,1.5)

答案 2 :(得分:0)

正如其他人已经回答为什么Array[Any]可以包含String,Boolean,Int等类型的元素让我回答问题的以下部分

  

如果它是错的那么我们在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

在上面的代码中,您的list类型为HList,其中包含IntStringBoolean类型的三个元素。当您检索HList的元素时,会保留元素的原始类型,并且您不会像在Array的情况下那样获得类似Any的泛型类型。这是可能的,因为HList不仅存储数据,还存储元素的类型信息,并在检索时正确地转换它们。