2011-01-28 61 views
6

时,我不明白为什么下面的代码不会编译:省略点链接调用

class Abc 
{ 
    def b (x : String) = x + "abc" 

    def a (y : String) = 
    { 
     val ls : List[String] = y.lines toList 
     b (ls.head) 
    } 
} 

Main.scala:8:错误:类型不匹配; 发现:java.lang.String中 需要的:int B(ls.head)

当我改变 “y.lines toList” 到

y.lines.toList 

或甚至

y.lines toList; 

它确实编译。

也许编译器能像

(y.lines).toList(b (ls.head)) 

或类似的东西,但我还是不明白的规则。

+0

你可以在REPL中插入你的语句'(y.lines).toList(b(ls.head)) '(嗯,也许你这样做了吗?)来验证错误消息是否相同。那么 - 我做到了,事实上,它是。 :) – 2011-01-28 03:04:27

回答

1

这并不明显,它是Scala快捷方式语法和列表索引的组合。如果你想有一个提示,尝试重新定义b到:

def b(x : String) = 0 

你会得到一些其他的编译器的垃圾回来,但错误会发生变化。简而言之,Scala编译器会让你省略零参数或单参数方法的零部件和点,并且我们知道b看起来像是以某种方式获得链接。蹭的是Scala也使用parens进行列表索引,因此toList返回一个迭代器,可能需要一个参数作为列表索引。我完全不确定这一部分,但看起来像一旦你开始省略点号,词法分析器就会变得贪婪,当它遇到一个可能需要一个参数的方法时,会尝试将下一个语句传递给它。在这种情况下,这是一个字符串,因此会引发语法错误。

1

你得到它发现与此:

(y.lines).toList(b (ls.head)) 

随着唯一可能的修正之中:

(y.lines).toList(b).apply(ls.head) 

我不知道这会斯卡拉在这种特殊情况下决定。

粗略地说,该规则是object (method parameters)* [method]。编译器将继续,只要它找到有效表达式的标记。 A ;完成表达,并且)}也将完成。如果下一行是空白,表达式也结束。如果下一行以保留关键字(valdefif等)开头,则表达式也会结束。