Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Array[String] not a subclass of Seq[String] in Scala?

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(" "))
like image 225
Björn Jacobs Avatar asked Jul 17 '12 12:07

Björn Jacobs


2 Answers

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.

like image 191
axel22 Avatar answered Oct 10 '22 17:10

axel22


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.

like image 44
Malte Schwerhoff Avatar answered Oct 10 '22 17:10

Malte Schwerhoff