scala 为什么Scala中需要`unary_`前缀?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16644988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 05:18:20  来源:igfitidea点击:

Why is the `unary_` prefix needed in scala?

scala

提问by jhabbott

Beginner Scala question, but I couldn't find the answer on here.

初学者 Scala 问题,但我在这里找不到答案。

Similar to overloading in C++, I would expect the compiler can tell the difference between a method called -which takes one parameter (with the same type as the class) and the unary version of -which takes no parameters, so why is unary_needed?

与 C++ 中的重载类似,我希望编译器可以区分调用的方法之间的区别,该方法-接受一个参数(与类具有相同的类型)和-不接受参数的一元版本,那么为什么unary_需要呢?

回答by J?rg W Mittag

The unary_prefix for unary prefix operatorsis a bit misleading: it's more about the prefixpart than the unarypart. You need some way to distinguish

一元前缀运算符unary_前缀有点误导:它更多是关于前缀部分而不是一元部分。你需要一些方法来区分

!foo // unary prefix !

from

foo! // unary postfix !

Remember: Scala doesn't actually have operators. There are two ways to call a method, either with a .or with whitespace:

请记住:Scala 实际上没有运算符。有两种方法可以调用方法,.使用空格或空格:

foo.bar(1, "two")
foo bar(1, "two")

And when you have a single argument, you can leave off the parentheses:

当你只有一个参数时,你可以去掉括号:

foo plus(1)
foo plus 1

Lastly, (almost) anycharacter is legal in an identifier:

最后,(几乎)任何字符在标识符中都是合法的:

foo plus 1
foo + 1

Now it lookslike Scala has a binary infix +operator, but it actually doesn't. It's just a normal method called with normal method calling syntax.

现在看起来Scala 有一个二元中缀+运算符,但实际上没有。它只是一个用普通方法调用语法调用的普通方法。

What I said above isn't fullytrue, however. If Scala didn't have support for operators and it all was just normal method calling, then

然而,我上面所说的并不完全正确。如果 Scala 不支持运算符,而这只是普通的方法调用,那么

2 + 3 * 4

would evaluate to 20 (like it does in Smalltalk, Self and Newspeak for example) instead of 14. So, there is a littlebit of support for operators in Scala (two little bits, actually). When a method is called with whitespace (so-called "operator syntax") instead of the ., and that method starts with an operator character, then Scala will respect operator precedence.

将计算为 20(就像在 Smalltalk、Self 和 Newspeak 中所做的那样)而不是 14。因此,Scala 中对运算符有一点支持(实际上是两点)。当使用空格(所谓的“运算符语法”)而不是 调用.方法时,该方法以运算符字符开头,则 Scala 将尊重运算符优先级。

And the other little bit of operator support is that there are some operators that you would liketo have, but that cannot be easily expressed as a method call. It works fine for binary infix operators and unary postfix operators:

和运营商的支持其它有点是,有一些运营商,你会希望有,但不能简单地表示为方法调用。它适用于二元中缀运算符和一元后缀运算符:

foo op bar // same as:
foo.op(bar)

foo op     // same as:
foo.op

But not for prefix or "around-fix" operators:

但不适用于前缀或“around-fix”运算符:

!foo
foo(bar)

So, there are a couple of special syntactic sugar translation rules:

因此,有一些特殊的语法糖翻译规则:

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

And the reason why there needs to be an underscore between the alphanumeric and the "operator" part in a method name is because you wouldn't know whether

方法名称中的字母数字和“运算符”部分之间需要有下划线的原因是因为您不知道

foo!

means

方法

foo.!

or

或者

this.foo!

Thus, foo!as a method name is illegal, it needs to be called foo_!.

因此,foo!由于方法名称是非法的,因此需要调用它foo_!

回答by drexin

Because in scala it is totally fine to create a method named -, that takes no arguments. How would you distinguish between a normal and a unary method? For example !has a totally different meaning as unary, than as post fix operator.

因为在 scala 中创建一个名为 的方法完全-没问题,它不需要参数。你如何区分普通方法和一元方法?例如,!作为一元的含义与作为后修复运算符的含义完全不同。