2017-02-05 14 views
1

* как известно, scala-массив содержит данные того же типа. Но когда я объявил массив какScala Array с разными типами данных

var a = new Array[Any](3) 

Я могу хранить различные типы данных.

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

как это возможно? если это неправильно, то какой вариант у нас есть в scala для хранения разных типов данных? *

+1

Я думаю, что правильный ответ для этого слишком широк. Пожалуйста, проконсультируйтесь с одним из многих учебных пособий Scala. –

+0

. Ваш вопрос предполагает, что вы понимаете, что значение имеет только один уникальный тип. Но это не так - на языке с подтипированием значение может быть одновременно членом многих типов. –

ответ

3

Понятие «того же типа» всегда зависит от уровня общности. В 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 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 имеют одинаковый тип Animal. Поэтому нет проблем с размещением 5, "hello" и 1.5 в Array[Any].

1

Да Вы правы насчет 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, чтобы удовлетворить свойству Массив, что он может hold elements of same type only. И в этом случае Any является супертипом всех классов, удовлетворяет условию. И, если компилятор не может найти общий супертип, создание массива завершится неудачно.

Обратите внимание, что это не только массив, то же самое для других collections, которые хранят same types .for например: Список

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

, что это вариант мы имеем в Скале для хранения различных типов данных?

Как вы можете видеть, что мы не в состоянии preserve the type of elements здесь в обоих List и Array. Все элементы хранятся как Any. Для сохранения типов элементов и хранить их вместе, Scala предоставляет нам Tuple:

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

Как и другие ответили, почему Array[Any] могут иметь элементы типов String, Boolean, Int и т.д. позвольте мне ответить ниже часть вопроса

, если это не так, то, что это вариант мы имеем в Скале для хранения различных типов данных? *

наиболее очевидный ответ является 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 с тремя элементами типов Int, String и Boolean. И когда вы извлекаете элементы HList, оригинальный тип элементов сохраняется, и вы не получаете такой общий тип, как Any, как в случае с Array. Это возможно, потому что HList хранит не только данные, но и информацию о типе элементов, а также их поиск.