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

Arrays 具有不同数据类型的Scala数组,arrays,scala,any,Arrays,Scala,Any,*正如我们所知,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。但是,

*正如我们所知,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
类型(我们非常欢迎在Scala中这样做),我们可能会编写

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 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)
当然青蛙和狗都可以进去,因为在
动物
的一般性水平上,青蛙和狗都有相同的类型


在Scala
中,Any
是所有其他类型派生的基类型。因此,在非常高的通用性水平上,
5
“hello”
,和
1.5
,它们都具有相同的类型
Any
,就像在较高的通用性水平上
青蛙
具有相同的类型
动物
。因此,将
5
“hello”
1.5
放入
数组[Any]
中没有问题

是的,关于
scala数组
你是对的,你确实在这里存储了
相同类型的数据。请参见此示例:

scala> val a = Array(5,"hello",1.5)
a: Array[Any] = Array(5, hello, 1.5)
我们没有看到创建了包含
整数
字符串
双精度
的数组。我们看到创建了任何
数组。在
数组创建过程中
,scala编译器在层次结构中查找最接近的
公共超类型
,以满足数组的属性,即它只能
保存相同类型的元素
。在这种情况下,
Any
作为所有类的超类型,满足条件。而且,如果编译器找不到公共超类型,数组创建将失败

请注意,它不仅适用于数组,还适用于存储相同类型的其他
集合

scala> val list = List(5,"hello",1.5)
list: List[Any] = List(5, hello, 1.5)
scala中存储不同数据类型的选项是什么?

正如您所见,我们无法在
列表
数组
中保留元素的类型。所有元素都存储为
Any
。为了保存元素类型并将它们存储在一起,scala为我们提供了
Tuple

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

正如其他人已经回答了为什么
Array[Any]
可以有String、Boolean、Int等类型的元素。让我回答下面的问题

如果它是错误的,那么我们在scala中有什么存储选项 不同的数据类型*

最明显的答案是。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
的val
列表
,其中包含三种类型的元素
Int
String
Boolean
。当您检索
HList
中的元素时,元素的原始类型将被保留,并且您不会像数组那样获得像
Any
这样的泛型类型。这是可能的,因为
HList
不仅存储数据,还存储元素的类型信息,并在检索时正确地强制转换它们。

我认为正确的答案过于宽泛。请参考众多Scala教程中的一个。您的问题表明您认为某个值只有一个唯一的类型。但事实并非如此——在具有子类型的语言中,一个值可以同时是多个类型的成员。支持具有不同类型的数组是否是一种好的做法(除非有类似于示例中的层次结构)?这可能会导致严重的铸造错误