3

你好堆栈溢出,

我希望你能在这里帮助我解决我的第一个问题:)

所以我遇到了 Scala 类型推断的问题。这是代码:

object Problem {

  def ok(fn: (String) => Unit) = fn("")

  // type mismatch; found: java.lang.String("") required: String
  def fail[String](fn: (String) => Unit) = fn("")

}

Scala 在这里期望什么样的字符串?

请注意,这是解释我的问题的最小示例。当我尝试实现更复杂的接口(确切地说是 Play 的 Iteratee)时,出现了最初的问题,所以,不,省略[String]不是一种选择。(如果有人认为实际代码会有所帮助,我会提供。)

我试过def fail[java.lang.String] ...了,但它说expected ], found .

我确实阅读了Scala String vs java.lang.String - 类型推断java.lang.String,它对vs.给出了很好的解释scala.Predef.String,但我仍然无法为我的具体问题提出解决方案。

有任何想法吗?

编辑:所以这是我尝试实现 http://www.playframework.org/documentation/api/2.0/scala/play/api/libs/iteratee/Iteratee.html的最初尝试,只是我写String的而不是T. (用T它编译,这是有道理的!)我的失败;显然我对所有类型参数有点不知所措:

val stream = WS.url("url").get({ headers =>
  (new Iteratee[Array[Byte], String] {
    def fold[T](done: (String, Input[Array[Byte]]) => Promise[T],
                cont: (Input[Array[Byte]] => Iteratee[Array[Byte], String]) => Promise[T],
                error: (String, Input[Array[Byte]]) => Promise[T]): Promise[T] =
    {
      done("something", Input.Empty)
    }
  })
})

问候, 亨德里克

4

2 回答 2

9

当你写:

def fail[String](fn: (String) => Unit) = fn("")

方括号之间的类型参数String只是一个任意名称,在您的情况下,它将隐藏 scala 或 java 字符串。它完全等同于:

def fail[T](fn: (T) => Unit) = fn("")

如果要将类型限制为字符串,则只需编写:

def fail(fn: (String) => Unit) = fn("")

它适用于 scala 和 java 字符串(因为它们是相同的)。

于 2012-04-05T12:06:35.773 回答
1

这个问题与 Java vs Scala 字符串无关。

在这一行中def fail[String](fn: (String) => Unit) = fn(""),您定义了一个全新的类型参数并将其命名为 String。这掩盖了一般定义。

如果您打算对类型进行抽象,则需要类型参数。您在示例中没有这样做fail,应该删除它。

如果您要覆盖使用类型参数的内容,则应在class级别指定:

class A extends B[String]

查看 Iteratee 的代码,我猜您正在尝试fold使用它的各种done,conterror函数来实现。Fold 只有一个类型参数,用于返回类型,所以我不确定它来自哪里。输入类型参数是在类上指定的,因此如果您扩展Iteratee[String, Unit]这些参数,则应提供这些参数。

于 2012-04-05T12:09:31.443 回答