scala介绍
- Scala语言来自于Scalable(可伸缩的)既可以写一些小的脚本,又可以写一写复杂的服务器端的程序。
- Scala是一门纯正的面向对象语言,具有OO特征。
- Scala是一门函数式语言,可以用函数式思想来编写代码
- Scala是构建于JVM之上的,与java可以无缝互操作。
函数式编程思想
函数式编程基本名词介绍
纯函数来编写程序。
- 纯函数(Pure Function),或函数的纯粹性(Purity)没有副作用(side Effect)
- 副作用是状态的变化
- 例子
- 修改全局变量
- 抛出异常
- IO读写
- 调用有副作用的函数
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> x = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> XplusY_V1(y:Int) = x + y <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> XplusY_V2(y:Int) = {x += y;x} </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
上面第一个函数是输入一个int类型的y,第二个函数是输入一个int类型的y返回值是x。
第二个函数相对于第一个函数对变量x产生了副作用。改变了x的值。
* 引用透明(Referential Transparency)对于相同的输入,总能得到相同的输出。
如果f(x)的参数x和函数体都是引用透明的,那么函数f是纯函数。
违反引用透明
- 不变性(Immutability)为了获得引用透明性,任何值都不能发生变化。
-
函数是一等公民(First-class Function)一切都是计算,函数式编程中只有表达式,变量、函数都是表达式。
函数也可以作为参数或者返回值。 -
表达式求值策略:严格求值和非严格求职。
Call By Value属于严格求值
Call By Name属于非严格求职 - 惰性求值(Lazy Evaluation)当定义这个变量时不会立即求值,只有在使用到这个变量时才会求值。
- 递归函数(Recursive Function)
在函数式编程中没有循环语句,所有的循环都要用递归来实现。
递归有个性能问题。容易堆栈溢出。
* 尾递归(Tail Recursion)
函数式编程的优点
- 生产效率高
同样的功能,Lisp(世界上第一个函数式编程语言)代码长度可能是C代码长度的七到十分之一。 - 易于推理
- 并行编程
因为是纯函数,所以不会引起线程紊乱。 - 多核计算、云计算
搭建scala环境
安装JDK
下载JDK最新版本,将环境变量添加到配置文件中
安装Scala的运行环境和包
从http://www.scala-lang.org/download上下载了Scala的最新版本,将环境变量添加到配置文件中就可以用了。
REPL(Read Evaluate Print Loop)就是scala命令行的运行环境。
在linux命令行输入scala就可以直接进入到scala REPL中。
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">devil<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@devilshome</span>:~$ scala Welcome to Scala <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.12</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.0</span>-M4 (Java HotSpot(TM) <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">64</span>-Bit Server VM, Java <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.8</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.0</span>_60). Type in expressions <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> evaluation. Or <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> :help. scala> println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Hello World"</span>) Hello World scala> </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
println()函数在所有Scala代码中都可用。
<code class="hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> x =<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> x: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> x = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> x: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> scala> </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
var 和 val 的区别稍后解释。
使用eclipse开发scala
在http://scala-ide.org/download/sdk.html下载专为scala的eclipse
- new一个Scala Project
- new 一个Scala Worksheet
worksheet是可以在IDE中直接进行代码的运行和结果的获得,是交互式的。
默认直接生成一个Object
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">worksheet</span> {</span> println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Welcome to the Scala worksheet"</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> Welcome to the Scala worksheet</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> x = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> x : Int = 1</span> println(x) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> 1</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
输入代码以后保存,会直接把输出的结果打印在右边。
新建一个package demo01
在package中新建一个scala app
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> demo01 <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Greeting</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">App</span> {</span> println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Hello,"</span>+args(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"!"</span>) }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
运行时设置main class和参数,main class的格式为包名.类名。
在控制台查看打印输出的结果
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Hello,Devil!</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
使用命令行编译scala
在文件夹中新建一个.scala文件,如Greeting.scala
在命令行中键入
<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">devil<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@devilshome</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:~/example</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>scalac <span class="hljs-constant" style="box-sizing: border-box;">Greeting</span>.scala</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
编译完成后,原文夹下多了一个Greeting.class文件,这个就是编译后的字节码文件。
再对这个字节码文件进行使用。
<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">devil<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@devilshome</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:~/example</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>scala <span class="hljs-constant" style="box-sizing: border-box;">Greeting</span> <span class="hljs-constant" style="box-sizing: border-box;">Jack</span> <span class="hljs-constant" style="box-sizing: border-box;">Hello</span>,<span class="hljs-constant" style="box-sizing: border-box;">Jack</span>! devil<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@devilshome</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:~/example</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$ </span>scala <span class="hljs-constant" style="box-sizing: border-box;">Greeting</span> <span class="hljs-constant" style="box-sizing: border-box;">Devil</span> <span class="hljs-constant" style="box-sizing: border-box;">Hello</span>,<span class="hljs-constant" style="box-sizing: border-box;">Devil</span>!</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
变量和表达式
变量
- var 自动生成读写接口,代表的是一个可变的有类型的存储单元。可以在定义变量时为它指定数据,而且可以在任何时间重新赋值。
- val 只生成了只读接口是一个不可变得、有类型的存储单元。可以在定义值时为它指定数据,不过不允许重新赋值,代表是一种函数式的思维。val蕴含了final的语义。
- lazy val 定义惰性求值的常量。
可以不显示指定变量的类型,因为Scala会自动进行类型推导。
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> x=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> x: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> y :Int =<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span> y: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span> scala> x+x res0: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span> scala> res0 res1: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span> scala> res0*res1 res2: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">400</span> scala> z=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span> <console>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>: error: reassignment to <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> z=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span> ^ <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//val的值不能被修改</span> scala> </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> d = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span> d: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span> scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> e = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span> e: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span> scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">lazy</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> f = d * e f: Int = <<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">lazy</span>> scala> f * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> res3: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6000</span> scala> f res4: Int = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">600</span> scala> </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>
精度问题
<code class="hljs vbnet has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> val b :<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Byte</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> b: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Byte</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> scala> val x :<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Long</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> x: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Long</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> scala> val y :<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Long</span> = b y: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Long</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> scala> val z : <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Byte</span> = x <console>:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">12</span>: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">error</span>: type mismatch; found : <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Long</span> required: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Byte</span> val z : <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Byte</span> = x ^ scala> </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>
- 字符类型
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> q = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'X'</span> q: Char = X</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
- Unit类型
Scala中的Unit类型类似于java中的void。主要的不同是在Scala中可以有一个Unit类型值,也就是(),然而java中是没有void类型的值的。除了这一点,Unit和void是等效的。一般来说每一个返回void的java方法对应一个返回Unit的Scala方法。
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> u : Unit=() u: Unit = () scala> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> p = () p: Unit = ()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
- Nothing
对于一个函数而言,如果返回值是nothing,则表名该函数发生了异常。
<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> def foo() = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Exception</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"error occurred"</span>) foo: ()Nothing</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
- String
构建于java的String之上。
新增了字符串插值(interpolation)的特性
<code class="language-shell hljs applescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> val <span class="hljs-property" style="box-sizing: border-box;">name</span> = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"devil"</span> <span class="hljs-property" style="box-sizing: border-box;">name</span>: String = devil scala> s<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"my name if ${name}"</span> res5: String = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">my</span> <span class="hljs-property" style="box-sizing: border-box;">name</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> devil </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
- Block
在scala中,代码块用于组织多个表达式,block也是一个表达式,其最终的求得的值是最后一个表达式的值。
函数
<code class="language-scala hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">func_wxamples</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> hello(name: String): String = { s<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello,${name}"</span> } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> hello: (name: String)String</span> hello(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"devil"</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> res0: String = hello,devil</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> hello2(name: String) = { s<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello,${name}"</span> } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> hello2: (name: String)String</span> hello2(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"devil"</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> res1: String = hello,devil</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> add (x:Int,y:Int) = x+y <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> add: (x: Int, y: Int)Int</span> add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> res2: Int = 8</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>
if表达式
在scala中,if是表达式,而不是语句。
<code class="hljs livecodeserver has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">object fun_if_example { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-constant" style="box-sizing: border-box;">true</span>) <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //> res0: Int = 1</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-constant" style="box-sizing: border-box;">false</span>) <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //> res1: Int = 4</span> val <span class="hljs-operator" style="box-sizing: border-box;">a</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //> a : Int = 1</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-operator" style="box-sizing: border-box;">a</span> == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) <span class="hljs-operator" style="box-sizing: border-box;">a</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //> res2: AnyVal = 1</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-operator" style="box-sizing: border-box;">a</span> != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"不是1"</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //> res3: Any = ()</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-operator" style="box-sizing: border-box;">a</span> != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"不是1"</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-operator" style="box-sizing: border-box;">a</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //> res4: Any = 1</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
for循环
<code class="hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">fun_for_examples</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> l = List(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"elisa"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"sin"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"satoshi"</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> l : List[String] = List(elisa, sin, satoshi)</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( s <- l <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用s循环遍历l中的元素</span> ) println(s) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> elisa</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//| sin</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//| satoshi</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> ( s <- l <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (s.length > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>) ) println(s) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> elisa</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//| satoshi</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> result_for = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> { s <- l s1 = s.toUpperCase() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (s1 != <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>) } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">yield</span> (s1) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> result_for : List[String] = List(ELISA, SIN, SATOSHI)</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>
yield (s1)的意思是将s放入一个新的collection中。
try表达式
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>{} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span>{} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span>{}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//无论有没有发生异常,我们都会执行finally这个代码块</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
match表达式
<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">exp match{ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> p1 => val1 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> p2 => val2 … <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> _ => valn }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
<code class="hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">func_match_example</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> code = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> code : Int = 3</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">val</span> result_match = code <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">match</span>{ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> => <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"one"</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> => <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"two"</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> _ => <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"three"</span> } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//> result_match : String = three</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
求值策略
scala里有两种求值策略(Evaluation Strategy)
- Call By Value 对函数实参求值,且仅求值一次
- Call By Name 对函数实参每次在函数体内被用到时都会求值。
scala通常使用 Call By Value
如果函数性参类型以 => 开头,那么会使用Call By Name
<code class="hljs sql has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">def foo(x:Int) = x //<span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Call</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">By</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Value</span> def foo(x:=><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Int</span>) = x //<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Call</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">By</span> Name</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="hljs vbscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">scala> def bar(x:<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span>,y: => <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span>)=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> bar: (x: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span>, y: => <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span>)<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span> scala> def <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">loop</span>(): <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span> = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">loop</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">loop</span>: ()<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span> scala> bar(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">loop</span>) res6: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> scala> bar(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">loop</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
第二个bar(loop,1)在进行死循环,因为x是Call By Value的需要对所有表达式求值才能进行下一步运算。
高阶函数
scala中函数是第一等公民
Scala语言支持:
1. 把函数作为实参传递给另外一个函数
2. 把函数作为返回值
3. 把函数赋值给变量
4. 把函数存储在数据结构中
在scala中,函数就像普通变量一样,同样也具有函数类型。
- 在scala中,函数类型的格式为 A=>B,表示一个接收类型A的参数,并返回类型B的函数。
高阶函数
用函数作为形参或返回值的函数,成为高阶函数
匿名函数
就是函数常量,也成为函数文字量。
在scala里,匿名函数的定一个是为(形参列表)=>{函数体}
柯里化
柯里化函数把具有多个参数的函数转换为一条函数链,每个节点上是单一参数。
eg:下面两个函数的定义是等价的
<code class="hljs vbscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">def add(x: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span>,y: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span>) = x+y</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
<code class="hljs vbscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">def add(x: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span>)(y: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Int</span>) = x+y</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
递归函数
递归函数在函数式变成中是实现循环的一种技术。
<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">factorial</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(n: Int)</span>:</span> Int = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (n<=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> n* factorial(n-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
尾递归
尾递归函数中所有递归形式的调用都出现在函数的末尾。
当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。
避免堆栈溢出
<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-decorator" style="color: rgb(0, 102, 102); box-sizing: border-box;">@annotation.tailrec //告诉scala编译器,对这个递归进行尾递归优化</span> <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">factorial</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(n: Int,m: Int)</span>:</span> Int = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (n<=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) m <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> factorial(n-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,m*n) factorial(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
在上面这个案例增加了一个m,m其实是保留了n*n-1*n-2……这样一个累乘器。
m永远拿到都是过去几次累乘的结果。