为什么Scala中需要`unary_`前缀? [英] Why is the `unary_` prefix needed in scala?
问题描述
初学者 Scala 问题,但我在这里找不到答案.
Beginner Scala question, but I couldn't find the answer on here.
类似于 C++ 中的重载,我希望编译器可以区分名为 -
的方法之间的区别,该方法采用一个参数(与类具有相同的类型)和 -
不带参数,为什么需要 unary_
?
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?
推荐答案
一元前缀运算符的unary_
前缀有点误导:它更多的是关于prefix 部分比 unary 部分.你需要一些方法来区分
The unary_
prefix for unary prefix operators is a bit misleading: it's more about the prefix part than the unary part. You need some way to distinguish
!foo // unary prefix !
来自
foo! // unary postfix !
请记住:Scala 实际上没有运算符.有两种方法可以调用方法,使用 .
或空格:
Remember: Scala doesn't actually have operators. There are two ways to call a method, either with a .
or with whitespace:
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) any character is legal in an identifier:
foo plus 1
foo + 1
现在看起来 Scala 有一个二进制中缀 +
运算符,但实际上没有.它只是一个普通方法调用的普通方法调用语法.
Now it looks like 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 fully true, however. If Scala didn't have support for operators and it all was just normal method calling, then
2 + 3 * 4
将计算为 20(例如在 Smalltalk、Self 和 Newspeak 中)而不是 14.因此,Scala 中对运算符有一点支持(实际上是两个小部分)).当使用空格(所谓的运算符语法")而不是 .
调用方法,并且该方法以运算符字符开头时,Scala 将尊重运算符优先级.
would evaluate to 20 (like it does in Smalltalk, Self and Newspeak for example) instead of 14. So, there is a little bit 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.
另外一点操作符支持是,您希望有一些操作符,但不能简单地表示为方法调用.它适用于二元中缀运算符和一元后缀运算符:
And the other little bit of operator support is that there are some operators that you would like to 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
但不适用于前缀或around-fix"运算符:
But not for prefix or "around-fix" operators:
!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!
意味着
foo.!
或
this.foo!
因此,foo!
作为方法名是非法的,需要调用foo_!
.
Thus, foo!
as a method name is illegal, it needs to be called foo_!
.
这篇关于为什么Scala中需要`unary_`前缀?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!