Scala:无法将数组传递给需要 Seq 或 Iterable 的函数
Posted
技术标签:
【中文标题】Scala:无法将数组传递给需要 Seq 或 Iterable 的函数【英文标题】:Scala: Can't pass an Array to a function where Seq or Iterable is expected 【发布时间】:2021-09-05 17:53:31 【问题描述】:我正在尝试编写一个通用函数,它接受一个类型参数 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 和这个函数仍然有效。有人可以帮我看看这是怎么回事吗?
【问题讨论】:
这是因为Array
来自 Java 领域并且位于标准 Scala 集合之外。它可以完成,但它不是微不足道的,并且在某种程度上取决于您正在运行的 Scala 版本。
【参考方案1】:
我知道 Scala 中的 Array 不是 Seq,但我希望它被隐式转换为 WrappedArray 并且这个函数仍然可以工作。有人可以帮我看看这是怎么回事吗?
这是怎么回事:
我希望它被隐式转换为 WrappedArray
你希望它不是真的。只有Scala Language Specification 里写的才是真的。
Section 3.2.6 Parameterized Types 表示“如果每个实际类型参数符合其界限,则参数化类型是格式良好的”。
而Section 3.5.2 Conformance 定义了“符合”的含义,并且没有在任何地方提及隐式转换。
因此,Array[String]
与Seq[String]
不一致,因此不是形式类型参数T
的有效实际类型参数。
【讨论】:
【参考方案2】:要返回与收到的相同的集合类型,包括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)
【讨论】:
以上是关于Scala:无法将数组传递给需要 Seq 或 Iterable 的函数的主要内容,如果未能解决你的问题,请参考以下文章