【问题标题】:Scala Array map returns ArraySeqScala 数组映射返回 ArraySeq
【发布时间】:2012-10-02 00:19:43
【问题描述】:

为什么我下面的工厂方法中不能有类型参数?

import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FunSuite

@RunWith(classOf[JUnitRunner])
class WhyScalaNeverWillMakeIt extends FunSuite {

  test("Array becomes ArraySeq when you least want it") {
    val arr = Array("A", "B", "C")
    def f: String => Dummy = new Dummy(_)

    val bucket = new Bucket[Dummy](arr.map(f))
//    val bucket2 = Bucket[String, Dummy](arr, f)
//    val bucket3 = Bucket[Dummy](arr, f)
    val bucket4 = Bucket(arr, f)
  }

  class Bucket[T]( val arr: Array[T] )  {/* Loads of business logic */}

  object Bucket {
//    def apply[T, U](arr: Array[T], f:T=>U):Bucket[U] = new Bucket[U](arr.map( b => f(b) ))
//    def apply[T](arr: Array[String], f:String=>T):Bucket[T] = new Bucket[T](arr.map( b => f(b) ))
    def apply(arr: Array[String], f:String=>Dummy):Bucket[Dummy] = new Bucket[Dummy](arr.map(f))
  }


  class Dummy(val name: String)
}

如果我取消注释 object Bucket 中的工厂方法,我会得到:

error: type mismatch;
found   : scala.collection.mutable.ArraySeq[T]
required: Array[T]
def apply[T](arr: Array[String], f:String=>T):Bucket[T] = new Bucket[T](arr.map( b => f(b) ))

当我引入类型参数 T 时,Scala 编译器不知何故感到困惑(或者是我?;-))。也许我在这里做错了什么,但我不明白为什么引入类型参数意味着map 函数应该将返回类型从 Array[T] 更改为 ArraySeq[T]。

我知道 Array 只是 Java Array 的包装器,我可能应该使用更花哨的 Scala 类之一,例如 Seq 或 List,但这仍然不能解释这种相当奇怪的行为。

有人可以解释为什么会发生这种情况以及如何解决它(仍然使用数组)吗?

编辑:我使用的是 scala 2.9.1

【问题讨论】:

    标签: scala


    【解决方案1】:

    只需添加ClassManifest 上下文绑定:

        def apply[T, U: ClassManifest](arr: Array[T], f: T => U): Bucket[U] = new Bucket[U](arr.map(b => f(b)))
        def apply[T: ClassManifest](arr: Array[String], f: String => T): Bucket[T] = new Bucket[T](arr.map(b => f(b)))
    

    详情请查看thisthis

    【讨论】:

    • 好的,谢谢 Sergey,成功了。现在我只需要阅读并理解您提供的链接。也许那里的某些东西会让我接受带有 [T: ClassManifest] 的丑陋 ++ 语法。
    • 我知道什么能让你接受这种语法,看看它的含义: def foo[T : Bar] 变成 def foo[T](implicit generatedName: Bar[T])
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2019-07-06
    • 2018-06-29
    • 1970-01-01
    相关资源
    最近更新 更多