【发布时间】:2013-05-14 17:50:47
【问题描述】:
初学者 Scala 问题,但我在这里找不到答案。
类似于 C++ 中的重载,我希望编译器能够区分名为 - 的方法之间的区别,该方法采用一个参数(与类具有相同的类型)和不带参数的 - 的一元版本,那么为什么需要unary_?
【问题讨论】:
标签: scala
初学者 Scala 问题,但我在这里找不到答案。
类似于 C++ 中的重载,我希望编译器能够区分名为 - 的方法之间的区别,该方法采用一个参数(与类具有相同的类型)和不带参数的 - 的一元版本,那么为什么需要unary_?
【问题讨论】:
标签: scala
一元前缀运算符的unary_前缀有点误导:它更多的是关于前缀部分而不是一元部分。你需要一些方法来区分
!foo // unary prefix !
来自
foo! // unary postfix !
记住:Scala 实际上没有运算符。调用方法有两种方式,使用. 或使用空格:
foo.bar(1, "two")
foo bar(1, "two")
当你有一个参数时,你可以去掉括号:
foo plus(1)
foo plus 1
最后,(几乎)任何字符在标识符中都是合法的:
foo plus 1
foo + 1
现在它看起来 Scala 有一个二进制中缀+ 运算符,但实际上没有。它只是一个普通的方法调用语法。
然而,我上面所说的并不完全正确。如果 Scala 不支持运算符,而这一切都只是普通的方法调用,那么
2 + 3 * 4
将评估为 20(就像在 Smalltalk、Self 和 Newspeak 中所做的那样)而不是 14。因此,Scala 中对运算符有一点支持(实际上是两个小位) )。当使用空格(所谓的“运算符语法”)而不是 . 调用方法时,并且该方法以运算符字符开头,那么 Scala 将尊重运算符优先级。
另外一点对操作符的支持是,有一些操作符是您喜欢 的,但它们不能轻易地表达为方法调用。它适用于二元中缀运算符和一元后缀运算符:
foo op bar // same as:
foo.op(bar)
foo op // same as:
foo.op
但不适用于前缀或“环绕修复”运算符:
!foo
foo(bar)
所以,有一些特殊的语法糖翻译规则:
!foo
foo.unary_!
// same for +, - and ~
foo(bar)
foo.apply(bar)
foo(bar) = 1
foo.update(bar, 1)
foo += 1
foo.+=(1) // but if this doesn't compile, then the compiler will also try
foo = foo.+(1)
而方法名称中的字母数字和“运算符”部分之间需要下划线的原因是因为您不知道是否
foo!
表示
foo.!
或
this.foo!
所以foo!作为方法名是非法的,需要调用foo_!。
【讨论】:
(2.) + (3.) * (4)。不过,您应该收到弃用警告;不推荐使用不带小数的浮点文字,并将在以后的版本中删除。
因为在 scala 中创建一个名为- 的方法是完全可以的,它不需要任何参数。您如何区分普通方法和一元方法?例如,! 作为一元的含义与作为后修复运算符的含义完全不同。
【讨论】:
!x 和x! 都被称为! 并且不使用额外的参数并且编译器会知道这是两个不同的函数?它还会知道调用哪一个,因为它是在对象之前还是之后?