def fn [String]似乎打破了Scala / java.lang.String的兼容性

时间:2012-04-05 12:00:52

标签: scala generics type-inference

你好Stack Overflow,

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

所以我遇到了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 - type inference,对java.lang.Stringscala.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)
    }
  })
})

此致 亨德里克

2 个答案:

答案 0 :(得分: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字符串(因为它们是相同的)。

答案 1 :(得分:1)

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

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

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

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

class A extends B[String]

查看Iteratee的代码,我猜你会尝试使用各种folddonecont函数来实现error。折叠只有一个类型参数,它在返回类型中使用,所以我不确定它可以来自何处。输入类型参数在类上指定,因此如果扩展Iteratee[String, Unit],则应提供这些参数。