我不明白为什么以下代码无法编译:
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 :(得分: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]
。只要它找到有效表达式的标记,编译器就会继续。 ;
完成表达式,)
或}
也是如此。如果下一行为空白,则表达式也将结束。如果下一行以保留关键字(val
,def
,if
等)开头,则表达式也将结束。