Scala:无法将数组传递给需要 Seq 或 Iterable 的函数

Scala: Can't pass an Array to a function where Seq or Iterable is expected

我正在尝试编写一个通用函数,它采用类型参数 T,它是 Seq[String] 的子集,下面是示例

def test[T <:Seq[String]](c:T):T = {
c
}

我定义了一个变量 Array[String]

val b = Array("test")

现在我期待它能工作,但是,我收到如下错误

scala> test(b)
       ^
       error: inferred type arguments [Array[String]] do not conform to method test's type parameter bounds [T <: Seq[String]]
            ^
       error: type mismatch;
        found   : Array[String]
        required: T

我尝试将 T 定义为 Iterable[String] 的子集,但这也不起作用。

我知道 Scala 中的 Array 不是 Seq,但我希望它被隐式转换为 WrappedArray 和这个函数仍然有效。谁能帮我看看这是怎么回事?

I understand that Array in Scala is not a Seq, but I was hoping it to be implicitly converted to WrappedArray and this function to still work. Can someone help me what is wrong with this?

这是怎么回事:

I was hoping it to be implicitly converted to WrappedArray

你希望它不会成真。只有 Scala Language Specification 中写的才是真实的。

Section 3.2.6 Parameterized Types 表示“如果每个实际类型参数 符合其边界 ,则参数化类型是良构的”。

Section 3.5.2 Conformance定义了“符合”的含义,并没有在任何地方提及隐式转换。

因此,Array[String] 符合 Seq[String],因此对于正式类型参数 T 而言,它不是有效的实际类型参数.

为了 return 与收到的相同 collection 类型,包括 Array,你必须使用一些特殊类型 类。

这是一个(不是特别好)的例子。 (Scala 2.13.x)

import scala.collection.Factory
import scala.collection.generic.IsIterable

def test[CC[_]](c:CC[String]
               )(implicit isit: IsIterable[CC[String]] {type A = String}
                        , fac : Factory[String,CC[String]]
                ): CC[String] =
  isit(c).map(_.reverse).to(fac)

test(Array("abc"))           //res0: Array[String] = Array(cba)
test(Vector("Go","Jo"))      //res1: Vector[String] = Vector(oG, oJ)
test(List("my","dad","Bob")) //res2: List[String] = List(ym, dad, boB)