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

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

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


当前回答

作为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")
}

其他回答

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

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

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

请记住以下几点:

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

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

你可以先根据某些标准对它们进行分组。在这篇文章中,我将只解释下划线字符和右箭头。

_._ 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:

val tup = ("Hallo", 33)
tup._1 // extracts "Hallo"
tup._2 // extracts 33

现在让我们假设函数应用程序快捷方式的用例。给定一个将整数映射到字符串的映射:

val coll = Map(1 -> "Eins", 2 -> "Zwei", 3 -> "Drei")

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") or 1 -> "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 object scala.Predef in scope. The conversion which takes place here is

implicit def any2ArrowAssoc [A] (x: A): ArrowAssoc[A] 

其中ArrowAssoc有->方法,用于创建Tuple2。因此,1 ->“Eins”实际上是调用Predef.any2ArrowAssoc(1).->(“Eins”)。好的。现在回到带有下划线字符的原始问题:

// lets create a sequence from the map by returning the
// values in reverse.
coll.map(_._2.reverse) // yields List(sniE, iewZ, ierD)

这里的下划线缩短了以下等效代码:

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

注意map的map方法将key和value的元组传递给函数参数。由于我们只对值(字符串)感兴趣,所以我们使用元组上的_2方法提取它们。

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)

只是为其他精彩的答案锦上添花。Scala提供了两个经常被批评的符号操作符,/:(foldLeft)和:\ (foldRight)操作符,第一个是右关联操作符。所以下面三个语句是等价的:

( 1 to 100 ).foldLeft( 0, _+_ )
( 1 to 100 )./:( 0 )( _+_ )
( 0 /: ( 1 to 100 ) )( _+_ )

就像下面这三个:

( 1 to 100 ).foldRight( 0, _+_ )
( 1 to 100 ).:\( 0 )( _+_ )
( ( 1 to 100 ) :\ 0 )( _+_ )

这里有很好的详尽的答案。

对我来说,关键的一点是,这有两类

op提到的符号是scala sdk中的函数名。在scala中,使用这些字符(包括unicode字符)来编写函数名是合法的。这将是一个很长的列表,试图从sdk中提到所有已经在其他答案中提到的问题

还有一些符号不是函数名,而是语言语法本身的一部分,如=>,_或操作符,如&&,||等。