楼主: Lisrelchen
3636 19

【GitBook】Scala 学习笔记 [推广有奖]

  • 0关注
  • 62粉丝

VIP

院士

67%

还不是VIP/贵宾

-

TA的文库  其他...

Bayesian NewOccidental

Spatial Data Analysis

东西方数据挖掘

威望
0
论坛币
49957 个
通用积分
79.5487
学术水平
253 点
热心指数
300 点
信用等级
208 点
经验
41518 点
帖子
3256
精华
14
在线时间
766 小时
注册时间
2006-5-4
最后登录
2022-11-6

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
Scala 学习笔记




二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:SCALA 学习笔记 习笔记 either 正则表达式 表达式 字符串

本帖被以下文库推荐

沙发
Lisrelchen 发表于 2017-2-21 02:02:03 |只看作者 |坛友微信交流群
  1. =====================
  2. 第二章 控制结构和函数
  3. =====================

  4. -----------
  5. 条件表达式
  6. -----------

  7. scala的 ``if/esle`` 语法结构与Java一样,但是在scala中 ``if/else`` 表达式有值,这个值就是跟在 ``if`` 或 ``else`` 之后表达式的值。

  8. 我们可以将 ``if/else`` 表达式的值赋予给变量:

  9. .. code-block:: scala

  10.         val s = if (x>0) 1 else -1

  11. 它等价于

  12. .. code-block:: scala

  13.         if (x>0) s = 1 else s = -1

  14. 不过,第一种写法更好,因为它可以用来初始化一个 ``val`` , 而第二种写法中, ``s`` 必须是 ``var`` 。


  15. 在Scala中,每个表达式都有一个类型。

  16. 如果是混合类型,则类型为 ``Any`` 。

  17. 如果 ``else`` 部分缺失,例如:

  18. .. code-block:: scala
  19.        
  20.         if (x>0) 1

  21. 等价于

  22. .. code-block:: scala
  23.        
  24.         if (x>0) else ()

  25. Scala没有 ``switch`` 语句,但是它有一个更强大的模式匹配机制。

  26. ----------
  27. 语句终止
  28. ----------

  29. 在scala中,分号绝大多数情况下都不是必须的。不过如果你想在单行中写下多个语句,则需要将它们以分号隔开。

  30. -----------------
  31. 块表达式和赋值
  32. -----------------

  33. 在Scala中, ``{}`` 包含一系列表达式,块中最后一个表达式的值就是块的值。

  34. 在Scala中赋值语句是没有值的,所以别把它们串接在一起。

  35. .. code-block:: scala
  36.        
  37.         x = y = 1 //别这样做

  38. -------------
  39. 输入和输出
  40. -------------

  41. 使用 ``print`` 或者 ``println`` 打印一个值。

  42. 使用 ``printf`` 格式化输出。

  43. 使用 ``readLine`` 从控制台读取一行输入,如果是读取数字, ``Boolean`` 或者字符串,可以使用 ``readInt`` ,  ``readDouble`` , ``readByte`` ,  ``readShort`` , ``readLong``, ``readFloat``, ``readBoolean``或者 ``readChar``。与其他方法不同,``readLine`` 带一个参数作为提示字符串。

  44. -----
  45. 循环
  46. -----

  47. scala支持 ``while`` 循环和 ``for`` 循环, ``while`` 循环与Java的 ``while``  一样, ``for`` 循环语法如下:

  48. .. code-block:: scala

  49.         for( i <- 表达式)

  50. 遍历字符串和数组时,你通常需要使用 ``0``  到 ``n-1`` 的区间,这个时候可以使用 ``until`` 方法而不是 ``to`` 方法。 ``until`` 方法返回一个并不包含上限的区间。

  51. -----------------------
  52. 高级for循环和for推导式
  53. -----------------------

  54. 可以使用变量 ``<-`` 表达式的形式提供多个生成器,用分号隔开。例如:

  55. .. code-block:: scala

  56.         for(i <-1 to 3, j <- 1 to 3) print ((10*i+j)+ " ")

  57. 每个生成器还可以带过滤条件,以 ``if`` 开头的 ``Boolean`` 表达式。

  58. .. code-block:: scala
  59.        
  60.         for(i <-1 to 3, j <- 1 to 3 if i != j) print ((10*i+j)+ " ")

  61. 还可以使用任意多的定义,引入可以在循环中使用的变量:

  62. .. code-block:: scala

  63.         for( i <- 1 to 3; from = 4-i; j <- from to 3)  print ((10*i+j)+ " ")

  64. 如果 ``for`` 循环的循环体以 ``yield`` 开始,则该循环会构造出一个集合,每次迭代出集合中的一个值:

  65. .. code-block:: scala

  66.         for( i <- 1 to 10) yield i % 3

  67. 这类循环叫做 ``for`` 推导式。

  68. -------
  69. 函数
  70. -------

  71. 要定义函数,需要给出函数的名称、参数和函数体:

  72. .. code-block:: scala

  73.         def abs(x:Double) = if (x>0) x else -x

  74. 必须给出所有参数的类型,不过,只要函数不是递归的,就不需要指定返回类型。Scala编译器可以通过 ``=`` 右侧的表达式推断出返回类型。

  75. 如果函数体需要多个表达式完成,可以使用代码块,块中最后一个表达式的值就是函数的返回值。


  76. 对于递归函数,必须指定返回类型。

  77. --------------------
  78. 默认参数和带名参数
  79. --------------------

  80. scala中可以给函数提供默认参数:

  81. .. code-block:: scala

  82.         def func(num:Int = 2) num += 3

  83. 还可以在提供参数值的时候指定参数名。带名参数不需要跟参数列表的顺序完全一致。

  84. ---------
  85. 变长参数
  86. ---------

  87. scala中还支持接收可变长度参数列表:

  88. .. code-block:: scala
  89.        
  90.         def sum(args: Int*){
  91.             var result = 0
  92.             for(arg <- args)
  93.                     result += arg
  94.             result
  95.         }


  96. 函数得到的是一个类型为 ``Seq`` 的参数。

  97. 如果你已经有一个值的序列,则不能直接将它传进上述函数。例如:

  98. .. code-block:: scala
  99.        
  100.         val s = sum(1 to 5) //错误

  101. 如果 ``sum`` 函数被调用时传入的是单个参数,那么该参数必须是单个整数,而不是一个整数区间。解决这个问题的办法是告诉编译器你希望这个参数被当作参数序列来处理,追加 ``:_*`` 。例如:

  102. .. code-block:: scala
  103.        
  104.         val s = sum(1 to 5: _*)


  105. --------
  106. 过程
  107. --------

  108. scala中不返回值的函数有特殊的表示法,如果函数体包含在花括号当中,但没有前面的 ``=`` 号,那么返回类型就是 ``Unit`` 。这样的函数称之为过程。

  109. 由于过程不返回值,所以我们省略 ``=`` 号。

  110. -----
  111. 懒值
  112. -----

  113. 当 ``val`` 被声明为 ``lazy`` 时,它的初始化将被推迟,直到我们首次对它赋值。

  114. .. code-block:: scala
  115.        
  116.         lazy val words = scala.io.Source.fromFile("a.txt").mkString


  117. 如果程序从不访问 ``a.txt`` ,那么它就不会被打开。
  118. 懒值对于初始化开销较大的初始化语句而言十分有用。

  119. -----
  120. 异常
  121. -----

  122. scala异常工作机制与Java一样,但是scala没有受检异常。

  123. ``throw`` 有特殊的类型值 ``Nothing`` ,这在 ``if/else`` 语句中特别有用,如果一个分支的类型是 ``Nothing`` ,那么 ``if/else`` 表达式的类型就是另一个分支的类型。

  124. 捕获异常的语法采用模式匹配的语法,更通用的异常应该排在更具体的异常后面。

  125. 如果不需要使用捕获的异常名,可以使用 ``_`` 代替变量名。
复制代码

使用道具

藤椅
Lisrelchen 发表于 2017-2-21 02:08:19 |只看作者 |坛友微信交流群
  1. =============
  2. 第三章 字符串
  3. =============

  4. 在Scala中,字符串也是不可变对象。

  5. ----------
  6. 创建字符串
  7. ----------

  8. .. code-block:: scala
  9.        
  10.         var greeting = "Hello, world"

  11.         // or

  12.         var greeting:String = "Hello, world"


  13. 如果需要使用可变字符串,可以使用 ``StringBuilder`` 类。

  14. -----------
  15. 字符串长度
  16. -----------

  17. 使用 ``length()`` 获取字符串长度。

  18. .. code-block:: scala
  19.        
  20.         object Demo {
  21.             def main(args: Array[String]) {
  22.                 var palindrome = "Dot saw I was Tod";
  23.                 var len = palindrome.length();
  24.                 println( "String Length is : " + len );
  25.             }
  26.         }


  27. -------------
  28. 拼接字符串
  29. -------------

  30. .. code-block:: scala
  31.        
  32.         string1.concat(string2);

  33.         // or

  34.         string1 + string2


  35. -------------
  36. 格式化字符串
  37. -------------

  38. 可以使用 ``printf`` 或者 ``format`` 来格式化字符串。 ``String`` 类有一个等价类的方法, ``format()`` ,它返回一个 ``String`` 对象,而不是一个 ``PrintStream`` 对象。

  39. .. code-block:: scala
  40.        
  41.         scala > "%.2f".format(1212)
  42.         1212.00
  43.        
  44. ----------
  45. 字符串插值
  46. ----------

  47. 字符串插值允许用户将变量的引用直接嵌入到处理字符串字面量中。例如:

  48. .. code-block:: scala
  49.        
  50.         val name = "James"
  51.         println(s"Hello, $name")    //Hello, James


  52. scala提供了三种字符串插值方法: ``s`` 、 ``f ``  和 ``raw``

  53. +++++++
  54. 插值器s
  55. +++++++

  56. 在任何字符串之前添加 ``s`` ,则该字符串允许直接包含变量。

  57. 字符串插值器也可以包含任意表达式:


  58. .. code-block:: scala

  59.         println(s" 1+1 = ${1+1}")


  60. ++++++++++++++
  61. 格式化插值器f
  62. ++++++++++++++

  63. 在任何字符串字面量前追加 ``f`` ,就可以创造一个简单的格式化字符串,类似于其他语言中的 ``printf`` 。
  64. 当使用插值器f时,所有变量的引用应该跟随 ``printf`` 风格的格式字符串,如同 ``%d`` 。
  65. 例如:

  66. .. code-block:: scala
  67.        
  68.         val height = 1.9d
  69.         val name = "James"
  70.         println(f"$name%s is $height%2.2f meters tail")  // James is 1.90 meters tall

  71. 插值器 ``f`` 是类型安全的。如果你试图传递一个只能工作于整数的格式化字符串,却又传了一个浮点数,编译器会发出一个错误。

  72. +++++++++++
  73. 插值器raw
  74. +++++++++++

  75. 插值器 ``raw`` 和插值器 ``s`` 相似,不同的是它不对字符串字面量执行转义。

  76. .. code-block:: scala
  77.        
  78.         scala> s"a\nb"
  79.         res0: String =
  80.         a
  81.         b

  82. 插值器 ``s`` 将字符 ``\n`` 替换成了回车符。而插值器 ``raw`` 不会这么做。

  83. .. code-block:: scala
  84.        
  85.         scala> raw"a\nb"
  86.         res1: String = a\nb

  87. 当你想要避免有表达式(例如 ``\n`` 变成回车)时,插值器 ``raw`` 是很有用的。
复制代码

使用道具

板凳
Lisrelchen 发表于 2017-2-21 02:10:42 |只看作者 |坛友微信交流群
  1. ===========
  2. 第四章 数组
  3. ===========

  4. --------
  5. 定长数组
  6. --------

  7. 如果需要一个长度不变的数组,可以使用scala中的 ``Array`` 。

  8. .. code-block:: scala

  9.         var z:Array[String] = new Array[String](3)
  10.         or
  11.         var z = new Array[String](3)

  12. --------
  13. 变长数组
  14. --------

  15. 变长数组使用 ``ArrayBuffer`` ,在数组缓存的尾端添加或者移除元素是一个高效的操作。

  16. 使用 ``toArray`` 将数组缓存转为数组,使用 ``toBuffer`` 将数组转成缓存。

  17. ------------------
  18. 遍历数组和数组缓存
  19. ------------------

  20. 使用 ``for`` 循环遍历数组或者缓存:

  21. .. code-block:: scala

  22.         for( i <- 0 until a.length)
  23.             println(i)

  24. 如果想每两个元素一跳,可以这样遍历:

  25. .. code-block:: scala

  26.         0 until (a.length,2)

  27. 如果想从数组的尾端开始,遍历写法为:

  28. .. code-block:: scala

  29.         (0 until a.length).reverse

  30. --------
  31. 数组转换
  32. --------

  33. 从一个数组出发,以某种方式对它进行转换,这些转换操作不会修改原数组,而是产生一个新的数组。

  34. .. code-block:: scala
  35.        
  36.         val a = Array(1,2,3,4)
  37.         val result = for(elem <- a) yield 2*elem

  38. 结果返回一个类型与原始集合相同的新集合。

  39. 我们也可以给转换增加过滤条件:

  40. .. code-block:: scala
  41.        
  42.         for(elem <- a if elem % 2 == 0) yield 2 * elem

  43. 注意原始集合并没有受到影响。

  44. 另一种做法是:

  45. .. code-block:: scala
  46.        
  47.         a.filter(_ % 2 == 0).map(2 * _)

  48. 甚至:

  49. .. code-block:: scala

  50.         a.filter{ _ % 2 == 0 } map {2 * _}

  51. --------
  52. 常用算法
  53. --------


  54. **求和**

  55. .. code-block:: scala
  56.        
  57.         Array(1,2,3).sum

  58. **最小值和最大值**

  59. .. code-block:: scala
  60.        
  61.         Array(1,2,3).min
  62.         Array(1,2,3).max

  63. **排序**

  64. .. code-block:: scala
  65.        
  66.         Array(5,2,1,4).sortWith(_ < _)

  67. **显示数组内容**

  68. .. code-block:: scala
  69.        
  70.         a.mkString
  71.         a.mkString(" and ")
  72.         a.mkString("<",",",">")

  73. --------
  74. 多维数组
  75. --------

  76. .. code-block:: scala

  77.         import Array._
  78.        
  79.         object Demo {
  80.                
  81.                 def main(args: Array[String]) {
  82.                         var myMatrix = ofDim[Int](3,3)
  83.                        
  84.                         // build a matrix
  85.                         for (i <- 0 to 2) {
  86.                                 for ( j <- 0 to 2) {
  87.                                         myMatrix(i)(j) = j;
  88.                                 }
  89.                         }
  90.                        
  91.                         // Print two dimensional array
  92.                         for (i <- 0 to 2) {
  93.                                 for ( j <- 0 to 2) {
  94.                                         print(" " + myMatrix(i)(j));
  95.                                 }
  96.                                 println();
  97.                         }
  98.                 }
  99.         }
复制代码

使用道具

报纸
雨季黎明 在职认证  发表于 2017-2-21 02:21:02 |只看作者 |坛友微信交流群
不错,很好的。

使用道具

地板
Lisrelchen 发表于 2017-2-21 02:22:13 |只看作者 |坛友微信交流群
  1. =======================
  2. 第五章 映射、选项以及元组
  3. =======================

  4. ---------
  5. 构造映射
  6. ---------

  7. **不可变映射**

  8. .. code-block:: scala

  9.         val score = Map("Alice"->80)

  10. **可变映射**

  11. .. code-block:: scala

  12.         val score = scala.collection.mutable.Map("Alice"-90)

  13. 在scala中,映射是一个对偶,对偶是两个值构成的组,这两个值不一定是同一类型。

  14. 使用 ``->`` 来创建对偶。


  15. **获取映射的值**


  16. 在scala中使用 ``()`` 表示法来查找某个键对应的值。

  17. .. code-block:: scala

  18.         val bobscore = scores("Bob")

  19. 如果映射并不包含请求中使用的键,则会抛出异常。

  20. 要检查映射中是否有某个指定的键,可以使用 ``contains()`` 方法。

  21. 除此之外,我们还可以使用 ``getOrElse()`` 方法。


  22. **更新映射中的值**



  23. 在可变映射中,可以更新映射值,做法是在 ``=`` 的左侧使用 ``()`` 。

  24. .. code-block:: scala

  25.         scores("Bob") = 10


  26. 也可以使用 ``+=`` 来添加多个关系

  27. .. code-block:: scala
  28.        
  29.         scores +=  ("Kate" -> 80)

  30. 使用 ``-=`` 移除某个键和对应的值。


  31. **迭代映射**

  32. 使用 ``for`` 循环遍历映射中所有的键:

  33. .. code-block:: scala
  34.        
  35.         for( (k, v) <- map)

  36. **访问键或者值**


  37. .. code-block:: scala
  38.        
  39.         scores.keySet
  40.         scores.values

  41. **反转映射**

  42. .. code-block:: scala
  43.        
  44.         for( (k, v) <- map) yield (v, k)

  45. **已排序映射**


  46. .. code-block:: scala

  47.         val scores = scala.collections.immutable.SortedMap("A"->1, "B"->2)

  48. 如果需要按插入顺序访问所有键的话,使用 ``LinkedHashMap`` 。

  49. ----
  50. 选项
  51. ----

  52. ``Option`` 是一个表示有可能包含值的容器。

  53. ``Option`` 基本的接口是这样的:

  54. .. code-block:: scala

  55.         trait Option[T] {
  56.           def isDefined: Boolean
  57.           def get: T
  58.           def getOrElse(t: T): T
  59.         }

  60. ``Option`` 本身是泛型的,并且有两个子类: ``Some[T]``  或  ``None``

  61. ``Map.get`` 使用 ``Option`` 作为其返回值,表示这个方法也许不会返回你请求的值。

  62. 模式匹配能自然地配合 ``Option`` 使用。

  63. .. code-block:: scala

  64.         val result = res1 match {
  65.           case Some(n) => n * 2
  66.           case None => 0
  67.         }

  68. -----
  69. 元组
  70. -----

  71. 元组是不同类型值的集合。

  72. .. code-block:: scala
  73.        
  74.         val t = (1, "a", 3.14)

  75. 和数组或字符串中的位置不同,元组从1开始而不是0。

  76. 在创建两个元素的元组时,可以使用特殊语法: ``->``:

  77. .. code-block:: scala

  78.         scala> 1 -> 2
  79.         res0: (Int, Int) = (1,2)

  80. 通常,使用模式匹配来获取元组的组员。

  81. .. code-block:: scala
  82.        
  83.         val (first , second, third ) = t

  84. 如果并不是所有的部件都需要,则可以在不需要的位置使用 ``_`` 。

  85. .. code-block:: scala
  86.        
  87.         val (first, second, _) =  t

  88. ------------
  89. 常用集合操作
  90. ------------

  91. +++
  92. Map
  93. +++

  94. ``map`` 对列表中的每个元素应用一个函数,返回应用后的元素所组成的列表。

  95. .. code-block:: scala

  96.         scala> numbers.map((i: Int) => i * 2)
  97.         res0: List[Int] = List(2, 4, 6, 8)

  98. 或者传入一个函数:

  99. .. code-block:: scala

  100.         scala> def timesTwo(i: Int): Int = i * 2
  101.         timesTwo: (i: Int)Int

  102.         scala> numbers.map(timesTwo _)
  103.         res0: List[Int] = List(2, 4, 6, 8)

  104. +++++++
  105. foreach
  106. +++++++

  107. ``foreach`` 很像 ``map`` ,但没有返回值。 ``foreach`` 仅用于有副作用的函数。

  108. .. code-block:: scala

  109.         scala> numbers.foreach((i: Int) => i * 2)

  110. 该函数返回值为Unit类型。

  111. ++++++
  112. filter
  113. ++++++

  114. ``filter`` 移除任何对传入函数计算结果为 ``false`` 的元素。返回一个布尔值的函数通常被称为谓词函数[或判定函数]。

  115. .. code-block:: scala

  116.         scala> numbers.filter((i: Int) => i % 2 == 0)
  117.         res0: List[Int] = List(2, 4)
  118.        
  119.         scala> def isEven(i: Int): Boolean = i % 2 == 0
  120.         isEven: (i: Int)Boolean

  121.         scala> numbers.filter(isEven _)
  122.         res2: List[Int] = List(2, 4)

  123. +++
  124. zip
  125. +++

  126. ``zip`` 将两个列表的内容聚合到一个对偶列表中。

  127. .. code-block:: scala

  128.         scala> List(1, 2, 3).zip(List("a", "b", "c"))
  129.         res0: List[(Int, String)] = List((1,a), (2,b), (3,c))

  130. +++++++++
  131. partition
  132. +++++++++

  133. ``partition`` 将使用给定的谓词函数分割列表。

  134. .. code-block:: scala

  135.         scala> val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  136.         scala> numbers.partition(_ % 2 == 0)
  137.         res0: (List[Int], List[Int]) = (List(2, 4, 6, 8, 10),List(1, 3, 5, 7, 9))

  138. ++++
  139. find
  140. ++++

  141. ``find`` 返回集合中第一个匹配谓词函数的元素。

  142. .. code-block:: scala

  143.         scala> numbers.find((i: Int) => i > 5)
  144.         res0: Option[Int] = Some(6)

  145. ++++++++++++++++
  146. drop & dropWhile
  147. ++++++++++++++++

  148. ``drop`` 将删除前i个元素

  149. .. code-block:: scala

  150.         scala> numbers.drop(5)
  151.         res0: List[Int] = List(6, 7, 8, 9, 10)

  152. ``dropWhile`` 将删除元素直到找到第一个匹配谓词函数的元素。例如,如果我们在numbers列表上使用 ``dropWhile`` 奇数的函数, 1将被丢弃(但3不会被丢弃,因为他被2“保护”了)。

  153. .. code-block:: scala

  154.         scala> numbers.dropWhile(_ % 2 != 0)
  155.         res0: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)

  156. ++++++++++++++++++++
  157. foldLeft & foldRight
  158. ++++++++++++++++++++

  159. .. code-block:: scala

  160.         scala> numbers.foldLeft(0)((m: Int, n: Int) => m + n)
  161.         res0: Int = 55
  162.        
  163. 0为初始值(记住numbers是 ``List[Int]`` 类型),m作为一个累加器。

  164. ``foldRight`` 和 ``foldLeft`` 一样,只是运行过程相反。

  165. +++++++
  166. flatten
  167. +++++++

  168. ``flatten`` 将嵌套结构扁平化为一个层次的集合。

  169. .. code-block:: scala

  170.         scala> List(List(1, 2), List(3, 4)).flatten
  171.         res0: List[Int] = List(1, 2, 3, 4)
  172.        
  173. +++++++
  174. flatMap
  175. +++++++

  176. ``flatMap`` 是一种常用的组合子,结合映射 ``[mapping]`` 和扁平化 ``[flattening]`` 。 ``flatMap`` 需要一个处理嵌套列表的函数,然后将结果串连起来。

  177. .. code-block:: scala

  178.         scala> val nestedNumbers = List(List(1, 2), List(3, 4))
  179.         nestedNumbers: List[List[Int]] = List(List(1, 2), List(3, 4))

  180.         scala> nestedNumbers.flatMap(x => x.map(_ * 2))
  181.         res0: List[Int] = List(2, 4, 6, 8)
  182.        
  183. 可以把它看做是“先映射后扁平化”的快捷操作。
复制代码

使用道具

7
Lisrelchen 发表于 2017-2-21 02:47:02 |只看作者 |坛友微信交流群
  1. =========
  2. 第六章 类
  3. =========

  4. ----------------
  5. 简单类和无参方法
  6. ----------------

  7. Scala类最简单的形式和Java相似:

  8. .. code-block:: scala

  9.     class Counter {
  10.         private var value = 0 //必须初始化
  11.         def increment() { value += 1}   //方法默认是公有的
  12.         def current () = value

  13. 在scala中,类并不声明为 ``public`` ,scala 源文件可以包含多个类,所有这些类都具有公有可见性。

  14. 调用无参方法时,可以使用圆括号,也可以不使用。一般的,对于改值器方法使用 ``()`` ,对于取值器方法则去掉 ``()`` 。

  15. 也可以使用不带 ``()`` 的方式声明 ``current`` 来强制调用的时候不使用 ``()`` 。

  16. --------------------------
  17. 带有getter和setter的属性
  18. --------------------------

  19. Scala对每一个字段都提供了 ``getter`` 和 ``setter`` 方法。这里定义一个公有字段:

  20. .. code-block:: scala

  21.     class Person {
  22.         var age = 0
  23.     }

  24. Scala生成面向JVM的类,其中有一个私有的 ``age`` 字段以及相应的 ``getter`` 和 ``setter`` 方法。这两个方法是公有的,因为我们没有将 ``age`` 声明为 ``private`` 。对于私有字段而言,``getter`` 和 ``setter`` 也是私有的。

  25. 在scala中,``getter`` 和 ``setter`` 分别叫做 ``age`` 和 ``age_=``。
  26. 例如:

  27. .. code-block:: scala

  28.     println(fred.age)
  29.     fred.age = 20

  30. 在任何时候你都可以自己重新定义 ``getter`` 和 ``setter`` 方法。

  31. 如果字段是 ``val`` ,则只有 ``getter`` 方法被生成。如果你不需要任何 ``getter`` 和 ``setter`` ,可以将字段声明为 ``private[this]`` 。

  32. -------------------
  33. 只带getter的属性
  34. -------------------

  35. 是用 ``val`` 字段,scala会生成一个 ``final`` 字段和一个 ``getter`` 方法。

  36. --------------
  37. 对象私有字段
  38. --------------

  39. 在scala中,方法可以访问该类的所有对象的私有字段。scala允许我们定义更加严格的访问限制,通过 ``private[this]`` 这个修饰符实现。

  40. .. code-block:: scala

  41.     private[this] val value = 0 //类似某个对象.value这样的访问将不被允许

  42. 这样的访问有时候称之为对象私有的。

  43. 对于类私有的字段,scala会生成私有的 ``getter``和 ``setter`` 方法,但对于对象私有的字段,scala根本不会生成 ``getter`` 和 ``setter`` 方法。

  44. scala允许将访问权赋予给指定的类,``private[类名]`` 修饰符可以定义仅有指定类的方法可以访问给定的字段。这里的类必须是当前定义的类,或者是包含该类的外部类。

  45. -------------
  46. 辅助构造器
  47. -------------

  48. 和Java一样,Scala也可以有任意多的构造器,包括主构造器与辅助构造器。

  49. 辅助构造器与Java的构造器类似,只有两处不同:

  50. * 辅助构造器的名称为 ``this``

  51. * 每一个辅助构造器都必须以一个对先前已定义的的其他辅助构造器或主构造器的调用开始。

  52. 下面的类中包含两个辅助构造器:

  53. .. code-block:: scala

  54.     class Person{
  55.         private var name = ""
  56.         private var age = 0
  57.         
  58.         def this(name:String) {
  59.             this()
  60.             this.name = name
  61.         }
  62.         
  63.         def this(name:String, age:Int){
  64.             this(name)
  65.             this.age = age
  66.         }
  67.     }


  68. 一个类如果没有显示定义主构造器则自动拥有一个无参的主构造器。

  69. 现在,我们可以使用三种方式构建对象:

  70. .. code-block:: scala

  71.     val p1 = Person
  72.     val p2 = Person("Jim")
  73.     val p3 = Person("Jim",12)

  74. ---------
  75. 主构造器
  76. ---------

  77. 在scala中,每个类都有主构造器,主构造器并不以 ``this`` 方法定义,而与类定义交织在一起。

  78. 1. 主构造器的参数直接放置在类名之后。

  79. .. code-block:: scala

  80.     class Person(val name:String, val age:Int){
  81.         ...
  82.     }


  83. 主构造器的参数被编译成字段,其值被初始化成构造时传入的参数。

  84. 2. 主构造器会执行类定义中的所有字段。例如:

  85. .. code-block:: scala

  86.     class Person(val name:String, val age:Int){
  87.         println("Just constructed another person")
  88.         ...
  89.     }


  90. ``println`` 语句是主构造器的一部分,每当有对象被构造出来的时候,上述代码就会被执行。当你需要再构造过程中配置某个字段的时候这个特性特别有用。


  91. 如果类名之后没有参数,则该类具备一个无参主构造器,这样的一个构造器仅仅简单的执行类体中的所有语句而已。

  92. 构造函数也可以是普通的方法参数,不带 ``val`` 或 ``var``。这样的参数如何处理取决于它在类中如何被使用。

  93. - 如果不带 ``val`` 或者 ``var`` 参数至少被一个方法所使用,它将被升格为字段。例如:

  94. .. code-block:: scala

  95.     class Person(name:String, age:Int){
  96.         def description = name + " is " + age + " years old"
  97.     }

  98. 上述代码声明并初始化了不可变字段的 ``name`` 和 ``age``。而这两个字段都是对象私有化的。类似这样的字段等同于 ``private[this] val`` 字段的效果。

  99. - 否则,该参数将不被保存为字段,它仅仅是一个可以被主构造器中的代码访问的普通参数表。

  100. 如果想让主构造器变成私有的,可以像这样放置 ``private`` 关键字。

  101. .. code-block:: scala

  102.     class Person private (val id:Int){
  103.         ...
  104.     }

  105. 这样一来,用户就必须通过辅助构造器来构造Person对象了。

  106. -------
  107. 嵌套类
  108. -------

  109. 在scala中,你几乎可以在任何语法结构中内嵌任何语法结构,你可以在函数中定义函数,也可以在类中定义类。
复制代码

使用道具

8
reflets 发表于 2017-2-21 02:55:20 |只看作者 |坛友微信交流群
感谢分享,如果可能的话,或许阅读英文原著对你的理解帮助更大。很多复杂的概念,原著比较容易理解。就好比外国人学习英文版的唐诗, 你可以想象的
已有 1 人评分论坛币 收起 理由
Nicolle + 20 鼓励积极发帖讨论

总评分: 论坛币 + 20   查看全部评分

使用道具

9
mssqlserver 发表于 2017-2-21 05:16:57 |只看作者 |坛友微信交流群
感谢分享
已有 1 人评分论坛币 收起 理由
Nicolle + 20 鼓励积极发帖讨论

总评分: 论坛币 + 20   查看全部评分

使用道具

10
katherinekongde 发表于 2017-2-21 05:30:20 |只看作者 |坛友微信交流群
感谢分享
已有 1 人评分论坛币 收起 理由
Nicolle + 20 鼓励积极发帖讨论

总评分: 论坛币 + 20   查看全部评分

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加JingGuanBbs
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-25 22:04