链接呼叫时省略点

时间:2011-01-28 02:12:54

标签: scala syntax

我不明白为什么以下代码无法编译:

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))

或类似的东西,但我仍然不理解规则。

2 个答案:

答案 0 :(得分:1)

这并不明显,它是Scala的快捷语法和列表索引的组合。如果您需要提示,请尝试将b重新定义为:

def b(x : String) = 0

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

答案 1 :(得分:1)

你明白了这一点:

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

唯一可能的纠正是:

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

我不确定Scala会在这种特殊情况下做出决定。

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