Scala 的所有符号运算符是什么意思?
Scala 语法有很多符号。由于使用搜索引擎很难找到这些类型的名称,因此完整的列表会很有帮助。
Scala 中的所有符号是什么?它们各自的作用是什么?
我特别想了解 ->
、||=
、++=
、<=< /code>、
_._
、::
和 :+=
。
Scala syntax has a lot of symbols. Since these kinds of names are difficult to find using search engines, a comprehensive list of them would be helpful.
What are all of the symbols in Scala, and what does each of them do?
In particular, I'd like to know about ->
, ||=
, ++=
, <=
, _._
, ::
, and :+=
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
出于教学目的,我将运算符分为四类:
幸运的是,大多数类别都在问题中得到了体现:
大多数这些方法的确切含义取决于定义它们的类。例如,
Int
上的<=
表示“小于或等于”。第一个,->
,我将在下面给出示例。::
可能是List
上定义的方法(尽管它可能是同名的对象),并且:+=
可能是在各种Buffer
类上定义的方法。那么,让我们看看他们。
关键字/保留符号
Scala 中有一些特殊的符号。其中两个被认为是正确的关键字,而其他的只是“保留”。它们是:
这些都是语言的一部分,因此可以在任何正确描述该语言的文本中找到,例如Scala 规范(PDF) 本身。
最后一个,下划线,值得特别描述,因为它被广泛使用,并且有很多不同的含义。这是一个示例:
不过,我可能忘记了其他一些含义。
自动导入的方法
因此,如果您在上面的列表中没有找到您要查找的符号,那么它一定是一种方法,或者是方法的一部分。但是,通常,您会看到一些符号,并且该类的文档不会包含该方法。发生这种情况时,要么您正在查看一个或多个方法与其他内容的组合,要么该方法已导入到作用域中,或者可以通过导入的隐式转换使用。
这些仍然可以在 ScalaDoc 上找到:您只需要知道在哪里寻找它们即可。或者,如果失败,请查看 索引(目前在 2.9.1 上损坏,但每晚可用)。
每个 Scala 代码都有三个自动导入:
前两个仅使类和单例对象可用。第三个包含所有隐式转换和导入方法,因为
Predef
本身就是一个对象。查看
Predef
内部很快就会显示一些符号:任何其他符号都将通过隐式转换变得可用。只需查看标记有
implicit
的方法,这些方法接收接收该方法的类型的对象作为参数。例如:在上面的例子中,
->
在类ArrowAssoc
通过采用A
类型对象的方法any2ArrowAssoc
,其中A
是一个同一方法的无界类型参数。常见方法
因此,许多符号只是类上的方法。例如,如果您这样做,
您将在 ScalaDoc 上找到 列表。但是,在搜索方法时必须注意一个约定。以冒号 (
:
) 结尾的方法将绑定到右侧而不是左侧。换句话说,虽然上面的方法调用相当于:如果我有,而不是
1 :: List(2, 3)
,那将相当于:所以你需要查看找到的类型当查找以冒号结尾的方法时,在右侧。例如,考虑一下:
第一个方法 (
+:
) 绑定到右侧,并且可以在List
上找到。第二个方法 (:+
) 只是一个普通方法,并且绑定到左侧 - 同样是在List
上。语法糖/组合
因此,这里有一些可能隐藏方法的语法糖:
最后一个很有趣,因为任何符号方法都可以组合起来形成类似赋值的方法。
当然,代码中可以出现各种组合:
I divide the operators, for the purpose of teaching, into four categories:
It is fortunate, then, that most categories are represented in the question:
The exact meaning of most of these methods depend on the class that is defining them. For example,
<=
onInt
means "less than or equal to". The first one,->
, I'll give as example below.::
is probably the method defined onList
(though it could be the object of the same name), and:+=
is probably the method defined on variousBuffer
classes.So, let's see them.
Keywords/reserved symbols
There are some symbols in Scala that are special. Two of them are considered proper keywords, while others are just "reserved". They are:
These are all part of the language, and, as such, can be found in any text that properly describe the language, such as Scala Specification(PDF) itself.
The last one, the underscore, deserve a special description, because it is so widely used, and has so many different meanings. Here's a sample:
I probably forgot some other meaning, though.
Automatically imported methods
So, if you did not find the symbol you are looking for in the list above, then it must be a method, or part of one. But, often, you'll see some symbol and the documentation for the class will not have that method. When this happens, either you are looking at a composition of one or more methods with something else, or the method has been imported into scope, or is available through an imported implicit conversion.
These can still be found on ScalaDoc: you just have to know where to look for them. Or, failing that, look at the index (presently broken on 2.9.1, but available on nightly).
Every Scala code has three automatic imports:
The first two only make classes and singleton objects available. The third one contains all implicit conversions and imported methods, since
Predef
is an object itself.Looking inside
Predef
quickly show some symbols:Any other symbol will be made available through an implicit conversion. Just look at the methods tagged with
implicit
that receive, as parameter, an object of type that is receiving the method. For example:In the above case,
->
is defined in the classArrowAssoc
through the methodany2ArrowAssoc
that takes an object of typeA
, whereA
is an unbounded type parameter to the same method.Common methods
So, many symbols are simply methods on a class. For instance, if you do
You'll find the method
++
right on the ScalaDoc for List. However, there's one convention that you must be aware when searching for methods. Methods ending in colon (:
) bind to the right instead of the left. In other words, while the above method call is equivalent to:If I had, instead
1 :: List(2, 3)
, that would be equivalent to:So you need to look at the type found on the right when looking for methods ending in colon. Consider, for instance:
The first method (
+:
) binds to the right, and is found onList
. The second method (:+
) is just a normal method, and binds to the left -- again, onList
.Syntactic sugars/composition
So, here's a few syntactic sugars that may hide a method:
The last one is interesting, because any symbolic method can be combined to form an assignment-like method that way.
And, of course, there's various combinations that can appear in code:
Scala 与其他语言之间的一个(良好的,IMO)区别是它允许您使用几乎任何字符来命名您的方法。
您列举的不是“标点符号”,而是简单明了的方法,因此它们的行为因一个对象而异(尽管有一些约定)。
例如,查看 List 的 Scaladoc 文档 ,您将看到此处提到的一些方法。
需要记住的一些事情:
大多数情况下,
A 运算符+等于 B
组合会转换为A = A 运算符 B
,如| 中所示。 |=
或++=
示例。以
:
结尾的方法是右关联的,这意味着A :: B
实际上是B.::(A)
。您可以通过浏览 Scala 文档找到大多数答案。在这里保留参考会重复工作,而且很快就会落后:)
One (good, IMO) difference between Scala and other languages is that it lets you name your methods with almost any character.
What you enumerate is not "punctuation" but plain and simple methods, and as such their behavior vary from one object to the other (though there are some conventions).
For example, check the Scaladoc documentation for List, and you'll see some of the methods you mentioned here.
Some things to keep in mind:
Most of the times the
A operator+equal B
combination translates toA = A operator B
, like in the||=
or++=
examples.Methods that end in
:
are right associative, this means thatA :: B
is actuallyB.::(A)
.You'll find most answers by browsing the Scala documentation. Keeping a reference here would duplicate efforts, and it would fall behind quickly :)
您可以首先根据某些标准对它们进行分组。在这篇文章中,我将仅解释下划线字符和右箭头。
_._
包含句点。 Scala 中的句点始终表示方法调用。因此,句点的左侧是接收者,右侧是消息(方法名称)。现在_
是 Scala 中的一个特殊符号。有几篇关于它的文章,例如 此博客条目< /a> 所有用例。这里它是一个匿名函数快捷方式,即它是一个函数的快捷方式,该函数接受一个参数并调用其方法_
。现在_
不是有效的方法,因此您肯定会看到_._1
或类似的内容,即调用方法_._1
关于函数参数。_1
到_22
是元组的方法,用于提取元组的特定元素。示例:现在让我们假设一个函数应用程序快捷方式的用例。给定一个将整数映射到字符串的映射:
Wooop,已经又出现了一个奇怪的标点符号。连字符和大于号字符类似于右手箭头,是一个生成
Tuple2
。因此,编写(1, "Eins")
或1 -> 的结果没有区别。 “Eins”
,只是后者更容易阅读,尤其是在像地图示例这样的元组列表中。->
并不神奇,它像其他一些运算符一样可用,因为您在对象scala.Predef
在范围内。这里发生的转换是ArrowAssoc
具有创建Tuple2
的->
方法。因此1 -> “Eins”
实际是调用Predef.any2ArrowAssoc(1).->(“Eins”)
。好的。现在回到带有下划线字符的原始问题:这里的下划线缩短了以下等效代码:
请注意,Map 的
map
方法将键和值的元组传递给函数参数。由于我们只对值(字符串)感兴趣,因此我们使用元组上的_2
方法提取它们。You can group those first according to some criteria. In this post I will just explain the underscore character and the right-arrow.
_._
contains a period. A period in Scala always indicates a method call. So left of the period you have the receiver, and right of it the message (method name). Now_
is a special symbol in Scala. There are several posts about it, for example this blog entry all use cases. Here it is an anonymous function short cut, that is it a shortcut for a function that takes one argument and invokes the method_
on it. Now_
is not a valid method, so most certainly you were seeing_._1
or something similar, that is, invoking method_._1
on the function argument._1
to_22
are the methods of tuples which extract a particular element of a tuple. Example:Now lets assume a use case for the function application shortcut. Given a map which maps integers to strings:
Wooop, there is already another occurrence of a strange punctuation. The hyphen and greater-than characters, which resemble a right-hand arrow, is an operator which produces a
Tuple2
. So there is no difference in the outcome of writing either(1, "Eins")
or1 -> "Eins"
, only that the latter is easier to read, especially in a list of tuples like the map example. The->
is no magic, it is, like a few other operators, available because you have all implicit conversions in objectscala.Predef
in scope. The conversion which takes place here isWhere
ArrowAssoc
has the->
method which creates theTuple2
. Thus1 -> "Eins"
is actual the callPredef.any2ArrowAssoc(1).->("Eins")
. Ok. Now back to the original question with the underscore character:The underscore here shortens the following equivalent code:
Note that the
map
method of a Map passes in the tuple of key and value to the function argument. Since we are only interested in the values (the strings), we extract them with the_2
method on the tuple.作为 Daniel 和 0__ 精彩答案的补充,我不得不说 Scala 理解 Unicode 类似物一些符号,因此
可以写
As an addition to brilliant answers of Daniel and 0__, I have to say that Scala understands Unicode analogs for some of the symbols, so instead of
one may write
关于
::
还有另一个 Stackoverflow 条目涵盖了::
案例。简而言之,它用于通过“consing”头元素和尾列表来构造列表
。它既是一个 类< /em> 表示一个 cons'ed 列表,可以用作提取器,但最常见的是它是列表上的方法。正如 Pablo Fernandez 指出的那样,由于它以冒号结尾,因此它是右结合,这意味着方法调用的接收者在右侧,参数在运算符的左侧。这样你就可以优雅地将 consing 表达为在现有列表中添加一个新的 head 元素:这相当于
作为提取器对象的使用如下:
这看起来像一个运算符,但它实际上是只是另一种(更易读)的写作方式
您可以在这篇文章中阅读有关提取器的更多信息。
Regarding
::
there is another Stackoverflow entry which covers the::
case. In short, it is used to constructLists
by 'consing' a head element and a tail list. It is both a class which represents a cons'ed list and which can be used as an extractor, but most commonly it is a method on a list. As Pablo Fernandez points out, since it ends in a colon, it is right associative, meaning the receiver of the method call is to the right, and the argument to the left of the operator. That way you can elegantly express the consing as prepending a new head element to an existing list:This is equivalent to
The use as extractor object is as follows:
This looks like an operator here, but it is really just another (more readable) way of writing
You can read more about extractors in this post.
<=
就像您“阅读”它一样:“小于或等于”。所以它是一个数学运算符,在<
(小于?)、>
(大于?)、==
(等于?)、!=
(不等于?)、<=
(小于或等于?)和>=(大于或等于?)。
这不能与
=>
混淆,后者是一种双右手箭头,用于将参数列表与正文分开函数的一部分,并将模式匹配中的测试条件(一个case
块)与匹配发生时执行的主体分开。你可以在我之前的两个答案中看到这个例子。首先,函数 use:已被缩写,因为省略了类型。以下函数将
与模式匹配一起使用:
<=
is just like you would "read" it: 'less than or equals'. So it's a mathematical operator, in the list of<
(is less than?),>
(is greater than?),==
(equals?),!=
(is not equal?),<=
(is less than or equal?), and>=
(is greater than or equal?).This must not be confused with
=>
which is kind of a double right-hand arrow, used to separate the argument list from the body of a function and to separate the testing condition in pattern matching (acase
block) from the body executed when a match occurs. You can see example of this in my previous two answers. First, the function use:which is already abbreviated as the types are omitted. The follow function would be
and the pattern matching use:
只是添加到其他优秀答案中。 Scala 提供了两个经常被批评的符号运算符,
/:
(foldLeft
) 和:\
(foldRight
) 运算符,首先是右结合。因此,以下三个语句是等效的:这三个语句也是等效的:
Just adding to the other excellent answers. Scala offers two often criticized symbolic operators,
/:
(foldLeft
) and:\
(foldRight
) operators, the first being right-associative. So the following three statements are the equivalent:As are these three:
我认为现代 IDE 对于理解大型 scala 项目至关重要。由于这些运算符也是方法,因此在 intellij idea 中我只需按住 Control 键单击或按 Control-B 键进入定义。
您可以按住 Control 键并右键单击 cons 运算符 (::),最后会出现 scala javadoc,显示“在此列表的开头添加一个元素”。在用户定义的运算符中,这变得更加重要,因为它们可以在难以找到的隐式中定义......您的 IDE 知道隐式是在哪里定义的。
I consider a modern IDE to be critical for understanding large scala projects. Since these operators are also methods, in intellij idea I just control-click or control-b into the definitions.
You can control-click right into a cons operator (::) and end up at the scala javadoc saying "Adds an element at the beginning of this list." In user-defined operators, this becomes even more critical, since they could be defined in hard-to-find implicits... your IDE knows where the implicit was defined.
Scala 继承了大部分 Java 算术运算符。这包括按位或
|
(单管道字符)、按位与&
、按位异或^
以及逻辑(布尔值)或||
(两个管道字符)和逻辑与&&
。有趣的是,您可以在boolean
上使用单字符运算符,因此 java'ish 逻辑运算符是完全多余的:正如另一篇文章中指出的,以等号
= 结尾的调用>,通过重新分配来解析(如果具有该名称的方法不存在!):
这种“双重检查”使得可以轻松地将可变集合交换为不可变集合:
Scala inherits most of Java's arithmetic operators. This includes bitwise-or
|
(single pipe character), bitwise-and&
, bitwise-exclusive-or^
, as well as logical (boolean) or||
(two pipe characters) and logical-and&&
. Interestingly, you can use the single character operators onboolean
, so the java'ish logical operators are totally redundant:As pointed out in another post, calls ending in an equals sign
=
, are resolved (if a method with that name does not exist!) by a reassignment:This 'double-check' makes it possible, to easily exchange a mutable for an immutable collection:
哦哦,所以你想要一个详尽的答案吗?这是一个有趣的、希望完整的、相当长的列表给你:)
http://jim-mcbeath.blogspot.com/2008/12/scala-operator-cheat-sheet.html
(免责声明 - 该帖子是写于 2008 年,所以可能有点过时了)
Oohoo so you want an exhaustive answer? Here's a fun, hopefully complete, and rather lengthy list for you :)
http://jim-mcbeath.blogspot.com/2008/12/scala-operator-cheat-sheet.html
(Disclaimer - the post was written in 2008 so may be a little out of date)
这里有很好的详尽答案。
对我来说一个关键点是这些有 2 类
op 提到的符号是 scala sdk 中的函数名称。在 scala 中,编写具有这些字符(包括 unicode 字符)名称的函数是合法的。这将是一个很好的长列表,尝试提及其他答案中已经提到的 sdk 中的所有符号
然后,有些符号不是函数名称,而是语言语法本身的一部分,例如
=>< /code>、
_
或运算符,例如&&
、||
等。There are good exhaustive answers here.
One key point for me is there are 2 categories of these
The symbols that the op has mentioned are function names in the scala sdk. In scala it is legal to write functions having names with these characters including unicode ones. It will be a good long list to try and mention all of them from the sdk that are already mentioned in the other answers
Then there are symbols that are not function names but part of the language syntax itself such as
=>
,_
or operators such as&&
,||
, etc.