斯卡拉的所有符号运算符是什么意思?

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
    

    大多数这些方法的确切含义取决于定义它们的类。 例如, <= on 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
    

    这些都是该语言的一部分,因此可以在正确描述该语言的任何文本中找到,例如Scala规范(PDF)本身。

    最后一个,下划线值得特别说明,因为它被广泛使用,并且有很多不同的含义。 这里有一个例子:

    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
    

    不过,我可能忘了其他一些意思。

    自动导入的方法

    所以,如果您在上面的列表中没有找到您要查找的符号,那么它必须是一种方法,或者是一种方法的一部分。 但是,通常情况下,您会看到一些符号,并且该类的文档将不会使用该方法。 发生这种情况时,无论是使用其他方法查看一个或多个方法的组合,还是已将该方法导入到作用域中,或者可通过导入的隐式转换来使用该方法。

    这些仍然可以在ScalaDoc上找到:您只需知道在哪里寻找它们。 或者,如果失败了,请查看索引(目前打破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本身就是一个对象。

    Predef里面快速显示一些符号:

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

    任何其他符号将通过隐式转换提供。 只要看看标记为implicit的方法,它接收作为参数的接收方法的类型的对象。 例如:

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

    在上述情况下, ->是在类定义ArrowAssoc贯穿方法any2ArrowAssoc这需要类型的对象A ,其中A是无界类型参数的相同方法。

    常用方法

    所以,许多符号只是一个类的方法。 例如,如果你这样做

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

    您将在ScalaDoc for List上找到方法++ 。 但是,搜索方法时必须注意一个约定。 方法结肠结束( : )绑定到右边而不是左边。 换句话说,虽然上面的方法调用相当于:

    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和其他语言之间的一个(良好的,IMO)区别在于它可以让你用几乎任何角色来命名你的方法。

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

    例如,查看List的Scaladoc文档,你会看到你在这里提到的一些方法。

    有些事情要记住:

  • 大多数情况下, A operator+equal B组合转换为A = A operator B ,就像在||=++=示例中一样。

  • 在End方法:是右关联,这意味着A :: B实际上是B.::(A)

  • 您将通过浏览Scala文档找到大多数答案。 在这里保持一个参考将重复努力,它会很快落后:)


    您可以根据一些标准将这些分组。 在这篇文章中,我只会解释下划线字符和右箭头。

    _._包含句点。 Scala中的一段时间总是表示一个方法调用 。 所以在你有接收器的时期剩下的时间内,它的权利就是消息(方法名称)。 现在_是Scala中的一个特殊符号 。 有几篇关于它的文章,例如这篇博客文章中的所有用例。 这里是一个匿名函数捷径 ,它是一个函数的快捷方式,它接受一个参数并调用其上的方法_ 。 现在_不是一个有效的方法,所以当然你会看到_._1或类似的东西,即在函数参数上调用方法_._1_1_22是提取元组的特定元素的元组方法。 例:

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

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

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

    Wooop,已经出现了另一个奇怪的标点符号。 连字符和大于号的字符(类似于右手箭头 )是生成Tuple2的操作符。 所以写作(1, "Eins")1 -> "Eins"的结果没有区别,只是后者更易于阅读,特别是在像地图示例这样的元组列表中。 ->没有什么魔力,就像其他一些操作符一样,因为在对象scala.Predef中有所有隐式转换, scala.Predef在范围中使用了scala.Predef 。 这里发生的转换是

    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方法提取它们。

    链接地址: http://www.djcxy.com/p/1999.html

    上一篇: What do all of Scala's symbolic operators mean?

    下一篇: Understanding the bitwise AND Operator