#scala #scala-2.13
Вопрос:
Почему я могу использовать to
для построения a Range
для первого аргумента Future.traverse
, но не until
могу ? См. Следующий пример взаимодействия с консолью Scala.
scala> Future.traverse(1 to 5)(Future.successful)
val res5: scala.concurrent.Future[IndexedSeq[Int]] = Future(<not completed>)
scala> Future.traverse(1 until 5)(Future.successful)
^
error: Cannot construct a collection of type scala.collection.immutable.AbstractSeq[Int] with elements of type Int based on a collection of type scala.collection.immutable.AbstractSeq[Int].
scala> res5
val res7: scala.concurrent.Future[IndexedSeq[Int]] = Future(Success(Vector(1, 2, 3, 4, 5)))
scala>
Обратите внимание, что я использую Scala 2.13.5 для консоли, хотя Scala 2.13.2, похоже, ведет себя так же.
Как бы то ни было, я заметил, что to
возвращается Range.Inclusive
, и until
возвращается Range.Exclusive
. Но оба они расширяются Range
, поэтому я не понимаю, чем отличаются эти два типа, так что Future.traverse
в качестве первого аргумента можно использовать один, но не другой.
Комментарии:
1. Похоже, это связано с открытой ошибкой , о которой сообщалось много лет назад. Проблема, похоже, исчезла в Scala 3.
2. Как бы то ни было, явная подпись типа исправит это.
Future.traverse[Int, Int, IndexedSeq](1 until 5)(Future.successful)
работает.3. Милые. Спасибо! Похоже, что сигнатура типа
Range
, начинающаяся с расширенияAbstractSeq
, а неIndexedSeq
на самом деле, имела значение.4. @LeoC Да, я думаю, что в этом ты прав!
Ответ №1:
Это выглядит как сочетание нескольких проблем.
1 until 5
возвращает a scala.collection.immutable.Range
, в то время 1 to 5
как возвращается Range.Inclusive
.
scala> val exclusive: Range.Exclusive = 1 until 5
^
error: type mismatch;
found : scala.collection.immutable.Range
required: Range.Exclusive
scala> val inclusive: Range.Inclusive = 1 to 5
val inclusive: Range.Inclusive = Range 1 to 5
Range.Inclusive
является конкретным классом и scala.collection.immutable.Range
является родителем обоих Range.Inclusive
и Range.Exclusive
. Похоже, что это связано с открытой ошибкой, о которой упоминал Лео Си, scala.collection.immutable.Range
рассматриваемой только AbstractSeq
, а не IndexedSeq
(как предполагал комментарий Сильвио Майоло). И AbstractSeq
не может быть сконструирован. Range.Inclusive
, будучи конкретным классом, не имеет такой же проблемы.
На данный момент я не уверен, почему AbstractSeq
это невозможно построить. Я думал , что причина в том, что AbstractSeq
это abstract
так, но IndexedSeq
это тоже черта характера. Тем не менее, это, вероятно, по замыслу AbstractSeq
не может быть построено, но IndexedSeq может.