scala中的flatMap函数
在下面两个场景中,我在列表中调用了flatMap函数。在这两种情况下,flatMap函数的map部分返回一个具有迭代器的数组。在第一种情况下,代码会出错,而在第二种情况下,它会生成预期的结果 情景1scala中的flatMap函数,scala,flatmap,Scala,Flatmap,在下面两个场景中,我在列表中调用了flatMap函数。在这两种情况下,flatMap函数的map部分返回一个具有迭代器的数组。在第一种情况下,代码会出错,而在第二种情况下,它会生成预期的结果 情景1 val x = List("abc","cde") x flatMap ( e => e.toArray) <console>:13: error: polymorphic expression cannot be instantiated to expected type; f
val x = List("abc","cde")
x flatMap ( e => e.toArray)
<console>:13: error: polymorphic expression cannot be instantiated to expected type;
found : [B >: Char]Array[B]
required: scala.collection.GenTraversableOnce[?]
x flatMap ( e => e.toArray)
你能帮我解释一下为什么在第一种情况下,它的表现不符合预期吗 正如错误所述,您的类型是错误的 在第一种情况下,如果应用map而不是flatmap,则获得List[Array[Char]]。如果对其应用展平,将得到一个列表[Char] 在第二种情况下,如果应用map而不是flatmap,则获得List[Array[String]]。如果对其应用展平,则会得到一个列表[字符串] 我想您需要将数组中的字符串转换为字符,以使其正常工作
我使用Scala 2.13,但仍然有相同的错误。我认为不同之处在于,在场景1中,实际上有一个
数组[B]
,其中B
是一些尚未确定的Char
超类型。通常,编译器会寻找到GenTraversableOnce
的隐式转换,但由于B
尚不清楚,因此会遇到类型推断问题/限制
scala> val x = List("abc","cde")
x: List[String] = List(abc, cde)
scala> x.flatMap[Char](_.toArray)
res0: List[Char] = List(a, b, c, c, d, e)
您可以通过填写B
来帮助进行类型推断
List("abc", "cde").flatMap(_.toArray[Char])
或者更好,在这种情况下,您不需要flatMap
。只需调用flatten
List("abc", "cde").flatten
值得记住的是,
Array
不是一个合适的Scala集合,因此编译器必须更加努力地将其转换为适合Scala集合其余部分的内容
implicitly[Array[Char] <:< GenTraversableOnce[Char]] // error (Scala 2.12)
implicitly[Array[Char] <:< IterableOnce[Char]] // error (Scala 2.13)
但我们正在通过
String => Array[Char]
编译器首先必须找到Array[Char]
到GenTraversableOnce[Char]
的适当隐式转换。也就是说,这应该是wrapCharArray
scala.collection.immutable.List.apply[String]("abc", "cde").flatMap[Char](((e: String) => scala.Predef.wrapCharArray(scala.Predef.augmentString(e).toArray[Char]((ClassTag.Char: scala.reflect.ClassTag[Char])))))
或更短
List("abc", "cde").flatMap(e => wrapCharArray(augmentString(e).toArray))
但是,由于Jasper-M解释的类型推断原因,编译器无法选择wrapcharray
conversion。正如所说的那样
Array
试图同时成为JavaArray
和Scala集合
时间它基本上成功了,但在某些极端情况下,两者都失败了
也许这是其中一个角落的情况。出于这些原因,最好避免使用阵列
,除非性能或兼容性原因另有规定。然而,另一种在Scala2.13中似乎有效的方法是使用to(Collection)
方法
List("abc","cde").flatMap(_.to(Array))
有趣
flatMap()
不会展平列表[Array[Char]]
(场景1),但会展平列表[Array[String]
(场景2)。在这两种情况下,如果您将flatMap()
更改为map()
,然后在最后添加。flatte
,它们都可以工作。@jwvh是的,工作正常。在上面的上下文中我有点困惑。我认为区别在于场景1中实际上有一个数组[B]
其中B
是Char
的一些尚未确定的超类型,它与搜索从Array
到GenTraversableOnce
的隐式转换相结合,会导致类型推断问题。顺便说一句,您可以直接拨打列表(“abc”、“cde”)。展平
。感谢您的关注。但即使在我的第二个例子中,我提供给flatMap的函数文字也会生成一个数组。谢谢您的回复。我只是在Scala控制台中复制并粘贴您的代码片段。它给出了错误(方法flatMap的类型参数数目错误…)。我有Scala 2.12.8。这在更高版本的Scala中是固定的吗?我在我的计算机上运行你的代码,我有2.13。我用我得到的更新了我的答案。
List("abc", "cde").flatMap(e => wrapCharArray(augmentString(e).toArray))
List("abc","cde").flatMap(_.to(Array))