【问题标题】:Foo does not take parameters compile error in Scala?Foo不接受Scala中的参数编译错误?
【发布时间】:2016-04-02 07:59:11
【问题描述】:

我有一个编译错误,我不明白。

case class Point(x: Int, y: Int)

trait Rectangular {

  def topLeft: Point
  def bottomRight: Point

  def left = topLeft().x //Compile error occurring here
  def right = bottomRight.x
  def width = right - left

  // any many more concrete geometric methods.
 }

我在定义第三个方法的那一行出现编译错误,提示“Point does not take parameters”。

但我认为你可以调用一个不带参数的函数,不管有没有()。因为topLeft只是一个没有参数的方法,返回类型为Point

【问题讨论】:

标签: scala function methods traits


【解决方案1】:

Scala 文档中描述了不同之处:

http://docs.scala-lang.org/style/method-invocation.html

简而言之,括号是用来标记有副作用的方法,所以不允许将0-arity(标记为)pure-method称为副作用。也可以看看: What is the rule for parenthesis in Scala method invocation?

它也与 UAP(统一访问原则)有关,因为没有() 的方法被解释为访问器,因此您可以将其实现为val

trait A { def a: Int } //for some reason it works with parenthesis as well
class B extends A { val a: Int = 5 }

所以这里someBInstance.a vs someATypedInstance.asomeBInstance.a vs someATypedInstance.a() 更好

除此之外,还有一个示例解释了为什么您不能将def f = ...() 一起使用——因为() 也用作调用apply 的快捷方式:

scala> class Z { def apply() = 5 }
defined class Z

scala> def f = new Z
f: Z

scala> f()
res87: Int = 5    

【讨论】:

  • 据我了解您的陈述:so it's not allowed to call pure-method as side-effectful,我认为这是误导。以下适用于 REPL - def f(): Int = 55。我认为“不允许”这个词意味着编译器将强制执行这样的限制。
  • @KevinMeredith 我专门为你添加了“标记为”;但是,我的意思是我的意思是,如果你写 def f(): Int = 5,这意味着你的方法是有副作用的,即使你当前的实现不是,因为你可能知道这个 f 可能会被一些不纯的东西覆盖
  • () 标记0-arity Unit-returning 方法表示副作用(stackoverflow.com/a/7606214/409976 作为参考)。我唯一的一点是(以防该语言的新手阅读它)它只是一种约定/样式 - 编译器不会强制执行它。
  • @KevinMeredith 除了 OP 所说的情况。我的意思是如果你有def f = 5(纯方法)编译器强制你总是称它为纯,你不能称它为副作用f()-“:27:错误:Int 不带参数”。或者很快“不允许调用(标记为)纯方法作为副作用。” :))))
  • @KevinMeredith 顺便说一句,这部分是因为 scala 也使用 () 来调用 apply 方法,否则很难决定(在某些情况下,比如在我更新的答案中)多少 @ 987654346@ 我们需要调用这样的方法(但是在这种情况下可以通过强制使用整个apply 来解决,所以这可能不是主要原因)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多