Arrays 具有不同数据类型的Scala数组
*正如我们所知,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。但是,
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教程中的一个。您的问题表明您认为某个值只有一个唯一的类型。但事实并非如此——在具有子类型的语言中,一个值可以同时是多个类型的成员。支持具有不同类型的数组是否是一种好的做法(除非有类似于示例中的层次结构)?这可能会导致严重的铸造错误