I wrote a method that accepts objects of all subclasses of Seq[String]. Unfortunately it won't accept an object of the type Array[String]. Is Array[String] not a subclass of Seq[String]?
scala> def test[T <: Seq[String]](x: T) = {}
test: [T <: Seq[String]](x: T)Unit
scala> val data = "This is a test string"
data: java.lang.String = This is a test string
scala> test(data.split(" "))
<console>:10: error: inferred type arguments [Array[java.lang.String]] do not conform to method test's type parameter bounds [T <: Seq[String]]
test(data.split(" "))
No, Array[String]
translates to regular JVM arrays, like the ones you see in Java: String[]
.
The reason why you see all the operations on Array[String]
that you see on other Scala Seq
collections is that there is an implicit conversion from Array[T]
to ArrayOps[T]
.
Do this:
def test[T <% Seq[String]](x: T) = {}
This is called a view bound. It means that T
should either be a subtype of Seq[String]
or there should exist an implicit conversion in scope which converts T
into a Seq[String]
. Behind the scenes, the compiler actually adds an implicit parameter to test
, so this method becomes:
scala> def test[T <% Seq[String]](x: T) = {}
test: [T](x: T)(implicit evidence$1: T => Seq[String])Unit
This implicit evidence$1
is the function which now acts as the implicit conversion from T
to Seq[String]
within the body of the method.
The sources (or the API docs) state, that Array
is defined as
final class Array[T] extends Serializable with Cloneable
That is, it is not a subtype of Seq
. However, the docs also mention an implicit conversion WrappedArray
, where the latter is a subset of Seq
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With