这两个调用函数采用结构类型集合之间的区别是什么?

时间:2010-05-16 20:18:05

标签: scala scala-2.8

为什么调用fn(Iterator(“foo”)编译,但对fn(fooIterator)的调用失败并显示错误“ type mismatch; found:Iterator [java.lang.String] required:scala .Iterator [com.banshee.Qx.HasLength]

object Qx {
    type HasLength = {def length: Int}
    def fn(xs: Iterator[HasLength]) = 3
    var tn = fn(Iterator("foo"))
    var fooIterator = Iterator("foo")
    var tnFails = fn(fooIterator) //doesn't compile
}

他们不是一回事吗?

2 个答案:

答案 0 :(得分:3)

这个表述有效:

object Qx {
    type HasLength = {def length: Int}
    def fn[HL <% HasLength](xs: Iterator[HL]) = 3
    val tn = fn(Iterator("foo"))
    val fooIterator = Iterator("foo")
    val tnFails = fn(fooIterator)
}

答案 1 :(得分:3)

它必须是改进表示中的错误,因为以下两个公式都有效。

object Qx1 {
    // give length() parens, even though the Iterator definition doesn't have them
    type HasLength = { def length(): Int }

    def fn(xs: Iterator[HasLength]) = 3
    var tn = fn(Iterator("foo"))
    var fooIterator = Iterator("foo")
    var tnFails = fn(fooIterator) //doesn't compile
}

object Qx2 {
    type HasLength = { def length: Int }

    def fn(xs: Iterator[HasLength]) = 3
    var tn = fn(Iterator("foo"))
    // annotate the type of fooIterator before the type inferencer can mis-infer
    var fooIterator: Iterator[HasLength] = Iterator("foo")
    var tnFails = fn(fooIterator) //doesn't compile
}

编辑:

早上太早了。它是带有length()方法的String,它有parens,这意味着它是正确的,你认为length和length()是相同的方法。 (这是我以前记录过的一个很好的小陷阱。)