Scala的所有符号运算符是什么意思? [英] What do all of Scala's symbolic operators mean?

查看:48
本文介绍了Scala的所有符号运算符是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Scala语法有很多符号.由于很难使用搜索引擎找到这类名称,因此将其完整列出会很有帮助.

Scala中的所有符号是什么,它们每个都做什么?

我特别想了解->||=++=<=_._:::+=.

解决方案

出于教学目的,我将运算符划分为四个类别:

  • 关键字/保留符号
  • 自动导入的方法
  • 常用方法
  • 语法糖/成分

很幸运,问题中代表了大多数类别:

->    // Automatically imported method
||=   // Syntactic sugar
++=   // Syntactic sugar/composition or common method
<=    // Common method
_._   // Typo, though it's probably based on Keyword/composition
::    // Common method
:+=   // Common method

大多数这些方法的确切含义取决于定义它们的类.例如,Int上的<=表示小于或等于" .第一个->,我将在下面给出示例. ::可能是在List上定义的方法(尽管可以是同名对象),而:+=可能是在各种Buffer类上定义的方法.

那么,让我们看看它们.

关键字/保留符号

Scala中有一些特殊的符号.其中两个被认为是正确的关键字,而其他两个仅被保留".他们是:

// Keywords
<-  // Used on for-comprehensions, to separate pattern from generator
=>  // Used for function types, function literals and import renaming

// Reserved
( )        // Delimit expressions and parameters
[ ]        // Delimit type parameters
{ }        // Delimit blocks
.          // Method call and path separator
// /* */   // Comments
#          // Used in type notations
:          // Type ascription or context bounds
<: >: <%   // Upper, lower and view bounds
<? <!      // Start token for various XML elements
" """      // Strings
'          // Indicate symbols and characters
@          // Annotations and variable binding on pattern matching
`          // Denote constant or enable arbitrary identifiers
,          // Parameter separator
;          // Statement separator
_*         // vararg expansion
_          // Many different meanings

这些都是语言的一部分,因此,可以在正确描述该语言的任何文本中找到它们,例如 ScalaDoc

上仍然可以找到

这些 a>:您只需要知道在哪里寻找它们.或者,如果失败,请查看索引(目前在2.9.1上已断开,但每晚可用).

每个Scala代码都有三个自动导入功能:

// Not necessarily in this order
import _root_.java.lang._      // _root_ denotes an absolute path
import _root_.scala._
import _root_.scala.Predef._

前两个仅使类和单例对象可用.第三个包含所有隐式转换和导入的方法,因为 是对象本身.

Predef内部快速浏览会显示一些符号:

class <:<
class =:=
object <%<
object =:=

其他任何符号都可以通过隐式转换使用.只需查看标记有implicit的方法,这些方法将接收该方法的类型的对象作为参数接收.例如:

"a" -> 1  // Look for an implicit from String, AnyRef, Any or type parameter

在上述情况下,->在类++. rel ="noreferrer">列表.但是,在搜索方法时必须注意一种约定.以冒号(:)结尾的方法将绑定到右侧,而不是左侧.换句话说,虽然上面的方法调用等效于:

List(1, 2).++(List(3, 4))

如果我有,而不是1 :: List(2, 3),那将等同于:

List(2, 3).::(1)

因此,在查找以冒号结尾的方法时,需要查看在右侧的 中找到的类型.例如,考虑:

1 +: List(2, 3) :+ 4

第一个方法(+:)绑定到右侧,并在List上找到.第二种方法(:+)只是普通方法,并绑定到左侧-再次在List上.

语法糖/成分

因此,这里有一些语法糖可能会隐藏方法:

class Example(arr: Array[Int] = Array.fill(5)(0)) {
  def apply(n: Int) = arr(n)
  def update(n: Int, v: Int) = arr(n) = v
  def a = arr(0); def a_=(v: Int) = arr(0) = v
  def b = arr(1); def b_=(v: Int) = arr(1) = v
  def c = arr(2); def c_=(v: Int) = arr(2) = v
  def d = arr(3); def d_=(v: Int) = arr(3) = v
  def e = arr(4); def e_=(v: Int) = arr(4) = v
  def +(v: Int) = new Example(arr map (_ + v))
  def unapply(n: Int) = if (arr.indices contains n) Some(arr(n)) else None
}

val Ex = new Example // or var for the last example
println(Ex(0))  // calls apply(0)
Ex(0) = 2       // calls update(0, 2)
Ex.b = 3        // calls b_=(3)
// This requires Ex to be a "val"
val Ex(c) = 2   // calls unapply(2) and assigns result to c
// This requires Ex to be a "var"
Ex += 1         // substituted for Ex = Ex + 1

最后一个很有趣,因为任何符号方法都可以通过这种方式组合成类似赋值的方法.

当然,在代码中可以出现各种组合:

(_+_) // An expression, or parameter, that is an anonymous function with
      // two parameters, used exactly where the underscores appear, and
      // which calls the "+" method on the first parameter passing the
      // second parameter as argument.

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 :+=.

解决方案

I divide the operators, for the purpose of teaching, into four categories:

  • Keywords/reserved symbols
  • Automatically imported methods
  • Common methods
  • Syntactic sugars/composition

It is fortunate, then, that most categories are represented in the question:

->    // Automatically imported method
||=   // Syntactic sugar
++=   // Syntactic sugar/composition or common method
<=    // Common method
_._   // Typo, though it's probably based on Keyword/composition
::    // Common method
:+=   // Common method

The exact meaning of most of these methods depend on the class that is defining them. For example, <= on Int means "less than or equal to". The first one, ->, I'll give as example below. :: is probably the method defined on List (though it could be the object of the same name), and :+= is probably the method defined on various Buffer 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:

// Keywords
<-  // Used on for-comprehensions, to separate pattern from generator
=>  // Used for function types, function literals and import renaming

// Reserved
( )        // Delimit expressions and parameters
[ ]        // Delimit type parameters
{ }        // Delimit blocks
.          // Method call and path separator
// /* */   // Comments
#          // Used in type notations
:          // Type ascription or context bounds
<: >: <%   // Upper, lower and view bounds
<? <!      // Start token for various XML elements
" """      // Strings
'          // Indicate symbols and characters
@          // Annotations and variable binding on pattern matching
`          // Denote constant or enable arbitrary identifiers
,          // Parameter separator
;          // Statement separator
_*         // vararg expansion
_          // Many different meanings

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:

import scala._    // Wild card -- all of Scala is imported
import scala.{ Predef => _, _ } // Exception, everything except Predef
def f[M[_]]       // Higher kinded type parameter
def f(m: M[_])    // Existential type
_ + _             // Anonymous function placeholder parameter
m _               // Eta expansion of method into method value
m(_)              // Partial function application
_ => 5            // Discarded parameter
case _ =>         // Wild card pattern -- matches anything
f(xs: _*)         // Sequence xs is passed as multiple parameters to f(ys: T*)
case Seq(xs @ _*) // Identifier xs is bound to the whole matched sequence

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:

// Not necessarily in this order
import _root_.java.lang._      // _root_ denotes an absolute path
import _root_.scala._
import _root_.scala.Predef._

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:

class <:<
class =:=
object <%<
object =:=

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:

"a" -> 1  // Look for an implicit from String, AnyRef, Any or type parameter

In the above case, -> is defined in the class ArrowAssoc through the method any2ArrowAssoc that takes an object of type A, where A 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

List(1, 2) ++ List(3, 4)

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:

List(1, 2).++(List(3, 4))

If I had, instead 1 :: List(2, 3), that would be equivalent to:

List(2, 3).::(1)

So you need to look at the type found on the right when looking for methods ending in colon. Consider, for instance:

1 +: List(2, 3) :+ 4

The first method (+:) binds to the right, and is found on List. The second method (:+) is just a normal method, and binds to the left -- again, on List.

Syntactic sugars/composition

So, here's a few syntactic sugars that may hide a method:

class Example(arr: Array[Int] = Array.fill(5)(0)) {
  def apply(n: Int) = arr(n)
  def update(n: Int, v: Int) = arr(n) = v
  def a = arr(0); def a_=(v: Int) = arr(0) = v
  def b = arr(1); def b_=(v: Int) = arr(1) = v
  def c = arr(2); def c_=(v: Int) = arr(2) = v
  def d = arr(3); def d_=(v: Int) = arr(3) = v
  def e = arr(4); def e_=(v: Int) = arr(4) = v
  def +(v: Int) = new Example(arr map (_ + v))
  def unapply(n: Int) = if (arr.indices contains n) Some(arr(n)) else None
}

val Ex = new Example // or var for the last example
println(Ex(0))  // calls apply(0)
Ex(0) = 2       // calls update(0, 2)
Ex.b = 3        // calls b_=(3)
// This requires Ex to be a "val"
val Ex(c) = 2   // calls unapply(2) and assigns result to c
// This requires Ex to be a "var"
Ex += 1         // substituted for Ex = Ex + 1

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:

(_+_) // An expression, or parameter, that is an anonymous function with
      // two parameters, used exactly where the underscores appear, and
      // which calls the "+" method on the first parameter passing the
      // second parameter as argument.

这篇关于Scala的所有符号运算符是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆