为什么我不能在Scala中写println"Hello world"?

mra*_*ers 23 scala

我对Scala很陌生,但我认为该语言的优势之一就是删除了例如Java中存在的括号和点的仪式.所以当我发现我可以写的时候,我很困惑

str1 equals str2
Run Code Online (Sandbox Code Playgroud)

但不是

println "Hello world"
Run Code Online (Sandbox Code Playgroud)

我猜测它与第一个例子有三个"部分"有关,但第二个例子只有两个,但我很难理解它为什么会这样.

Deb*_*ski 53

当只有两个部分时,表达式被视为方法调用.即唯一的可能性

println "Hello, world"
Run Code Online (Sandbox Code Playgroud)

将会

println."Hello, world"
Run Code Online (Sandbox Code Playgroud)

这当然没有多大意义.(*****见下文补充)

但是,如果您愿意,可以编写Console println "Hello, World"以解决歧义.

它看起来不像字符串示例中的ambigus,字符串很难成为方法名称,但请考虑以下内容:

class B
val b = new B

object A {
  def apply(myB: B) { print("apply") }
  def b { print("b") }
}
Run Code Online (Sandbox Code Playgroud)

现在,在写作时A b,我会得到什么.应该如何解释?事实证明:

A b // "b"
A.b // "b"
A(b) // apply
Run Code Online (Sandbox Code Playgroud)

因此,有一个明确的规则,即在两部分表达式中做什么.(我希望没有人开始分裂头发apply和真正的方法调用...)

加成

随着动态类的出现,你可以玩一下并定义以下内容

object println extends Dynamic {
  def typed[T] = asInstanceOf[T]
  def applyDynamic(name: String)(args: Any*) = Console.println(name)
}
Run Code Online (Sandbox Code Playgroud)

现在看!没有括号:

println `Hello, world` // prints, "Hello, world"
Run Code Online (Sandbox Code Playgroud)

当然,请不要在孩子面前或现实代码中这样做.


Rah*_*thy 5

您可以使用三个"部分"重写第二个示例,在这种情况下,它将在没有括号的情况下编译:

Predef println "Hello world"
Run Code Online (Sandbox Code Playgroud)

(仅用于说明目的 - @ Debilski的答案是完美的!)