Попытка понять коллекцию Range в Scala и почему возникают ошибки при назначении типа данных в Scala v2.13, а не v2.11 - PullRequest
0 голосов
/ 29 февраля 2020

Я прошу базовое c Scala обучение, предлагаемое здесь: https://www.lynda.com/Scala-tutorials/Scala-Essential-Training-Data-Science/559182-2.html и на вводном разделе, где инструктор представляет коллекции, он выполняет эти команды в REPL (используя Scala v2.11):

scala> val myRange = 1 to 10
myRange: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> val myRange2 : Range = new Range(1, 101, 2)
myRange2: Range = Range(1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99)

Предполагаемый тип становится типом объекта: scala.collection.immutable.Range.Inclusive, а явно типизированный - просто: Range.

Кроме того, в версии 2.13 из Scala (текущая версия, которую я установил до отката до версии для инструкторов), те же команды приводят к:

scala> val myRange = 1 to 10
myRange: scala.collection.immutable.Range.Inclusive = Range 1 to 10

scala> val myRange2 : Range = new Range(1, 101, 2)
                              ^
       error: class Range is abstract; cannot be instantiated

У инструктора нет никаких объяснений относительно этих типов, которые кажется, отличаются, и я изо всех сил пытаюсь понять, почему ошибка возникает в более новой версии Scala? Был ли класс Range ранее не абстрактным классом? И если да, то почему это изменилось?

Ответы [ 2 ]

3 голосов
/ 29 февраля 2020

В обратном порядке, да Scala 2,13 сделали Range абстрактным, если оно было ранее конкретным. Однако никогда не было необходимости использовать new для его создания, потому что val myRange2 = Range(1, 101, 2) будет работать очень хорошо, так что это ошибка в руководстве.

Метод to возвращает тип Range.Inclusive, который Вот почему это напечатано в REPL. Это подтип Range, поэтому он имеет все методы Range и может использоваться везде, где может использоваться Range.

new Range возвращает Range, поскольку он явно вызывает конструктор, поэтому он должен возвращать Range.

Обратите внимание, что если вы используете Range(1, 101, 2), это вернет Range в 2,12 и Range.Exclusive в 2,13.

2 голосов
/ 29 февраля 2020

Если сравнить страницу старше Range Scaladocs (в данном случае 2.12.7) с текущей Range страницей Scaladocs (2.13.1), видите, да, класс Range был изменен на abstract. Не уверен почему. Коллекции претерпели множество изменений с выпуском 2.13.

Что касается различных уточнений типа Range, то это потому, что to означает Inclusive, который не является типом Range по умолчанию.

Welcome to Scala 2.12.7 (OpenJDK 64-Bit Server VM, Java 11.0.6).
Type in expressions for evaluation. Or try :help.

scala> 2 to 8
res0: scala.collection.immutable.Range.Inclusive = Range 2 to 8

scala> 2 until 9
res1: scala.collection.immutable.Range = Range 2 until 9

scala> Range(2, 9)
res2: scala.collection.immutable.Range = Range 2 until 9

И в 2.13 произошли дальнейшие улучшения.

2 to 8      //res0: scala.collection.immutable.Range.Inclusive = Range 2 to 8
2 until 9   //res1: scala.collection.immutable.Range = Range 2 until 9
Range(2, 9) //res2: scala.collection.immutable.Range.Exclusive = Range 2 until 9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...