2010-05-16 55 views
3

为什么调用fn(Iterator(“foo”)进行编译,但调用fn(fooIterator)失败,并显示错误“类型不匹配;找到: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 
} 

他们不是一回事

+0

你可以发布迭代器的类型singnatures吗?可能有变异注释或暗示? – Dario 2010-05-16 20:26:16

+0

这只是标准库的东西,不需要额外的代码。 scala> Iterator(“foo”) res0:Iterator [java.lang.String] =非空迭代器 – 2010-05-16 20:31:14

回答

3

它必须是在代表一个bug改进,因为以下两个表单这两个工作。

​​

编辑:

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

+0

如果只是长度与长度(),他的第一个例子不应该失败吗? var tn = fn(Iterator(“foo”)) – 2010-05-17 20:54:33

+0

为什么Randall Schulz的版本使用视图投影?我有点困惑。 – 2010-05-17 22:43:06

+1

它只是长度与长度。 fn(Iterator(“foo”))的工作原因与注释fooIterator类型的工作原理相同:表达式的期望类型影响推断的类型。在失败的示例中,在声明中推断出不兼容的类型,然后在单独的语句中进行调用。 – extempore 2010-05-19 06:11:04

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) 
} 
+0

我很想统一解释这个评论和extempore关于zero-argument-length-vs-长度与 - 空括号。我有一种感觉,这里有一些微妙的变化,我不理解。 – 2010-05-17 22:40:21