Scala语法有很多符号。由于使用搜索引擎很难找到这些类型的名字,所以一个全面的列表将会很有帮助。

Scala中所有的符号都是什么,每个符号都有什么作用?

特别地,我想知道 ->, ||=, ++=, <=, _._,::,和:+=。


当前回答

Scala和其他语言的一个(在我看来是好的)区别是,它允许你用几乎任何字符来命名你的方法。

您列举的不是“标点符号”,而是简单明了的方法,因此它们的行为因对象而异(尽管存在一些约定)。

例如,查看Scaladoc文档中的List,您将看到这里提到的一些方法。

请记住以下几点:

大多数情况下,A操作符+= B组合转换为A = A操作符B,如||=或++=示例。 以:结尾的方法是右结合的,这意味着A:: B实际上是B.::(A)。

您可以通过浏览Scala文档找到大部分答案。在这里保留一个参考将重复工作,并且它将很快落后:)

其他回答

<=就像你会“读”它:'小于或等于'。所以它是一个数学运算符,在<(小于?)、>(大于?)、==(等于?)、!=(不等于?)、<=(小于或等于?)和>=(大于或等于?)的列表中。

这不能与=>混淆,后者是一种右向双箭头,用于将参数列表与函数体分离,并将模式匹配中的测试条件(case块)与匹配发生时执行的函数体分离。你可以在我之前的两个回答中看到这样的例子。一、函数使用:

coll.map(tup => tup._2.reverse)

它已经被缩写为省略了类型。接下来的函数是

// function arguments         function body
(tup: Tuple2[Int, String]) => tup._2.reverse

与模式匹配使用:

def extract2(l: List[Int]) = l match {
   // if l matches Nil    return "empty"
   case Nil            => "empty"
   // etc.
   case ::(head, Nil)  => "exactly one element (" + head + ")"
   // etc.
   case ::(head, tail) => "more than one element"
}

我认为现代IDE对于理解大型scala项目至关重要。由于这些操作符也是方法,在intellij思想中,我只是控制-单击或控制-b进入定义。

你可以右键点击一个cons操作符(::),然后在scala javadoc中说“在这个列表的开头添加一个元素”。在用户定义的操作符中,这一点变得更加关键,因为它们可能被定义为很难找到的隐式…你的IDE知道隐式的定义在哪里。

Scala继承了Java的大部分算术运算符。这包括位-或|(单个管道字符)、位-和&、位-异-或^,以及逻辑(boolean)或||(两个管道字符)和逻辑-和&&。有趣的是,你可以在布尔上使用单字符操作符,所以java的逻辑操作符是完全多余的:

true && true   // valid
true & true    // valid as well

3 & 4          // bitwise-and (011 & 100 yields 000)
3 && 4         // not valid

正如在另一篇文章中指出的那样,以等号=结尾的调用将通过重赋来解析(如果该名称不存在!):

var x = 3
x += 1         // `+=` is not a method in `int`, Scala makes it `x = x + 1`

这种“双重检查”使得可以轻松地将可变集合转换为不可变集合:

val m = collection.mutable.Set("Hallo")   // `m` a val, but holds mutable coll
var i = collection.immutable.Set("Hallo") // `i` is a var, but holds immutable coll

m += "Welt" // destructive call m.+=("Welt")
i += "Welt" // re-assignment i = i + "Welt" (creates a new immutable Set)

Regarding :: there is another Stackoverflow entry which covers the :: case. In short, it is used to construct Lists 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:

val x = 2 :: 3 :: Nil  // same result as List(2, 3)
val y = 1 :: x         // yields List(1, 2, 3)

这相当于

val x = Nil.::(3).::(2) // successively prepend 3 and 2 to an empty list
val y = x.::(1)         // then prepend 1

作为提取器对象的用法如下:

def extract(l: List[Int]) = l match {
   case Nil          => "empty"
   case head :: Nil  => "exactly one element (" + head + ")"
   case head :: tail => "more than one element"
}

extract(Nil)          // yields "empty"
extract(List(1))      // yields "exactly one element (1)"
extract(List(2, 3))   // yields "more than one element"

这看起来像一个运算符,但它实际上只是另一种(更可读的)书写方式

def extract2(l: List[Int]) = l match {
   case Nil            => "empty"
   case ::(head, Nil)  => "exactly one element (" + head + ")"
   case ::(head, tail) => "more than one element"
}

你可以在这篇文章中阅读更多关于提取器的信息。

作为Daniel和0__精彩回答的补充,我不得不说Scala理解某些符号的Unicode类比,所以代替

for (n <- 1 to 10) n % 2 match {
  case 0 => println("even")
  case 1 => println("odd")
}

你可以这样写

for (n ← 1 to 10) n % 2 match {
  case 0 ⇒ println("even")
  case 1 ⇒ println("odd")
}