【问题标题】:Using map to create a copy of an array (with generic type) results in error [Scala]使用 map 创建数组的副本(具有泛型)会导致错误 [Scala]
【发布时间】:2019-04-18 09:33:57
【问题描述】:

我正在尝试使用映射复制泛型类型的数组。

class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

  val internalCopy : Array[T] = arr.map(e => e) //This line

但我运行它给出了一个错误提示

found   : scala.collection.mutable.ArraySeq[T]
 required: Array[T]
 Note: implicit value comparison is not applicable here because it comes after the application point and it lacks an explicit result type
val internalCopy : Array[T] = arr.map(e => e)

我无法理解这一点。

【问题讨论】:

  • 你所指的问题已经很好解释了here
  • 那里并没有真正解释。有一个答案显示了解决方法,但没有解释为什么存在这种行为。

标签: scala implicit-conversion implicit


【解决方案1】:

所以,当编译时没有数组元素的类型信息时,问题是.map 返回ArraySeq 而不是Array。这是因为您需要有元素的实际类:Array.newInstance(clazz, numElements)。当您将元素类型指定为 T 时,这是不可用的,因此当您执行 .map 时,它会将容器类型切换为 ArraySeq 以解决该限制。

一种解决方法是将班级信息传递给您的班级:

class MaObj[T : ClassTag : Ordering](val arr : Array[T])

(这相当于class MaObj[T](val arr: Array[T])(implicit ev1: ClassTag[T], ev2: Ordering[T])

这将一个隐式参数传递给类,让它在运行时解析元素类型。

另一种方式,如果您真的只想复制数组而不转换其元素,您可以使用.clone,正如另一个答案所暗示的那样。它也更有效率。

或者只是使用IndexedSeq而不是Array开头,反正更好。

【讨论】:

    【解决方案2】:

    您可以使用.clone 轻松复制Array,而不是使用.map 结合身份的方法。

    您的代码如下所示:

    class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {
    
      val internalCopy: Array[T] = arr.clone
    
    }
    

    Try it out!

    我希望这会有所帮助。

    【讨论】:

    • 作为注释,数组的元素仍然是引用等价的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 2015-01-10
    相关资源
    最近更新 更多