Неявный класс, применимый ко всем подклассам Traversable, включая Array

Я столкнулся с проблемой, пытаясь создать неявный класс, применимый ко всем подклассам Traversable, включая Array. Я попробовал следующий простой пример как в Scala 2.11.1, так и в 2.10.4:

implicit class PrintMe[T](a: Traversable[T]) {
  def printme = for (b <- a) print(b)
}

Насколько я понимаю, это должно допускать неявное преобразование в PrintMe, чтобы printme можно было вызывать на любом Traversable, включая List и Array. Например:

scala> List(1,2,3).printme
123
// Great, works as I expected!

scala> Array(1,2,3).printme
<console>:23: error: value printme is not a member of Array[Int]
              Array(1,2,3).printme
// Seems like for an Array it doesn't!

scala> new PrintMe(Array(1,2,3)).printme
123
// Yet explicitly building a PrintMe from an Array works 

Что тут происходит? Почему неявное преобразование работает для списка, а не для массива?

Я понимаю, что были некоторые хитрости с адаптацией java-массивов, но, глядя на рисунок ниже с http://docs.scala-lang.org/overviews/collections/overview.html определенно кажется, что Array должен вести себя как подкласс Traversable.

scala.collection.immutable


person agrinh    schedule 19.08.2014    source источник
comment
AFAIK может применяться только одно неявное преобразование за раз. В этом случае я только догадываюсь об этом сейчас, возможно, уже происходит какое-то неявное преобразование из массивов java в массивы Scala - поэтому ваше преобразование не работает.   -  person goral    schedule 19.08.2014
comment
Обратите также внимание, что Array не является подтипом, этот символ означает, что scala имеет представление о классе массива из IndexSeq, что означает неявное преобразование.   -  person Ende Neu    schedule 20.08.2014


Ответы (1)


Как сказал @goral: одновременно может происходить только одно неявное преобразование.

Таким образом, вы можете передать массив, где ожидается Traversable, поскольку массив станет WrappedArray:

def printme[T](a: Traversable[T]) { for (b <- a) print(b) }
printme(Vector(1,2,3))
printme(Array(1,2,3))

Или вы можете использовать свое неявное значение в массиве, обернутом вручную:

val wa = scala.collection.mutable.WrappedArray.make(Array(1, 2, 3))
wa.printme

Но вы не можете иметь и то, и другое одновременно.

person dhg    schedule 19.08.2014