zoukankan      html  css  js  c++  java
  • 【转】Scala 片段2:List的操作符魔法

    原文链接 http://www.ituring.com.cn/article/131439

    本文翻译自:Scala snippets 2: List symbol magic fairjm@ituring


    Scala的每一个操作符都可以是函数,所以重载操作符(实际上不是真正的重载操作符,毕竟操作符都已经是方法了)

    是一件非常简单并且在很多库中都能看见的事。在这个片段中,我们将探讨一些让列表操作更加简单的方法重载。

    让我们从++操作符开始。首先,就像我们一直做的那样,让我们来创建一个列表:

    scala> val list = 0 until 10 toList
    list: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    
    scala> val list2 = 10 to 0 by -1 toList
    list2: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

    然后大致浏览下来自 http://www.scala-lang.org/api/2.11.1/index.html#scala.collection.immutable.List 的一些操作:

    第一个操作符是++。我们可以用这个操作符把两个列表连接在一起,并且返回一个新的列表:

    scala> val list3 = list ++ list2
    list3: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
    
    scala> val list3 = list2 ++ list
    list3: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

    注意你并不需要保证列表是相同类型的。Scala会自动选择最相关的父类:

    scala> val list1 = 0 to 10 toList
    list1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> val list2 = 10 to 0 by -1 toList
    list2: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
    
    scala> val list3 = list1.asInstanceOf[List[Double]]
    list3: List[Double] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> list3 ++ list2
    res4: List[AnyVal] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

    你可以看到最后的返回是AnyVal类型的列表,这是对于IntDouble最常见的父类。

    既然我们已经看过++了,让我们来看看和++看起来最相似的++:。这个操作符和++有着相同的语义,

    不同的地方是结果的类型在++中取决于左操作数而这个操作符取决于右操作数:

    scala> vector1
    res14: Vector[Int] = Vector(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
    
    scala> list1
    res15: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> vector1 ++ list1
    res16: scala.collection.immutable.Vector[Int] = Vector(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> vector1 ++: list1
    res17: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

    接下来的两个操作符:++:可以让我们向后和向前对列表增加新的元素:

    scala> 999 +: list1
    res27: List[Int] = List(999, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> list1 :+ 999
    res28: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 999)

    还有什么?:::::都是对列表之前增加一些东西的函数。::操作符增加单个元素,而:::操作符增加一个列表。

    所以基本上他们是和+:++操作一样的。主要的区别是+:++可以被用于Traversable,但:::::只能用于列表。

    scala> 11 +: list1
    res38: List[Int] = List(11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> list1
    res39: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> 11 +: list1
    res40: List[Int] = List(11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> list2
    res41: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
    
    scala> list1 ::: list2
    res43: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

    :/:用于折叠操作(看这里)。:从右至左折叠,而/:从左至右:

    scala> list1
    res50: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> (1 /: list1)((r,i) => {println(i);i+r})
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    res51: Int = 56
    
    scala> (list1 : 1)((i,r) => {println(i);i+r})
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    0
    res52: Int = 56

    你可以看到折叠的方向决定了元素是从前往后还是从后往前处理的。

    这就是这个片段的全部。

     
  • 相关阅读:
    MySQL IO线程及相关参数调优
    mysql InnoDB index 主键采用聚簇索引,二级索引不采用聚簇索引
    Mysql怎么判断繁忙 checkpoint机制 innodb的主要参数
    遇见 TiDB
    TiDB 深度实践之旅--真实“踩坑”经历
    tidb使用坑记录
    MySQL mysql server与存储引擎
    DBProxy 读写分离使用说明
    DBProxy 项目全解
    Mysql 数据库意向锁意义
  • 原文地址:https://www.cnblogs.com/ihongyan/p/4733311.html
Copyright © 2011-2022 走看看