ITPub博客

首页 > 数据库 > 数据库开发技术 > Scala快速入门-2-控制结构与函数

Scala快速入门-2-控制结构与函数

原创 数据库开发技术 作者:HelloTech技术派 时间:2018-01-01 21:33:14 0 删除 编辑

背景

  • 表达式有值,语句执行动作。

  • Scala中,几乎所有构造出来的语法结构都有值,不像Java中把表达式和语句(if语句)分为两类。

  • 在这里if表示式有值。

  • 代码块也有值,最后一个表达式就是值。

  • 语句中,分号不是必需的。

  • 函数式中不使用return。

条件表达式

  • 在Scala中if/else表达式有值,这个值就是在if或else之后的表达式的值。

  1. scala> var x = 10

  2. x: Int = 10

  3. scala> val r = if (x > 0) 1 else -1

  4. r: Int = 1

  5. scala> var x = 0

  6. x: Int = 0

  7. scala> val r = if (x > 0) 1 else -1

  8. r: Int = -1

  • 可能if没有输出值,但在Scala中,每个表达式都有某种值。

  1. scala> var x = 0

  2. x: Int = 0

  3. scala> val r = if (x > 0) 1

  4. r: AnyVal = ()

块表达式和赋值

  • 在Scala中{}块包含一系列表达式,其结果也是一个表达式。块中最后一个表达式的值就是块的值。

  • 对于某个val的初始化需要分多步完成的情况很实用。

  1. val dis = {val dx = x - x0; val dy = y - y0; sqrt(dx * dx + dy * dy)}

循环

  • while与Java中的循环一样。

  1. while(n > 0) {

  2.    r = r * n

  3.    n -= 1

  4. }

  • Scala没有for(初始化; 检查变量是否满足; 更新变量)的结构。

  1. for(i <- 1 to n) {

  2.    r = r * i

  3. }

  • 1 to n 表达式表示:返回数据1到n(包含)的区间。

  • 1 until n 表达式表示:返回数据1到n(不包含)的区间。

增强for循环和for推导式

  • 可以以 变量<-表达式的形式提供多个生成器,用分号将他们隔开

  1. scala> for(i <- 1 to 3; j <- 1 to 3) print ((10 * i + j) + " ")

  2. 11 12 13 21 22 23 31 32 33

  • 每个生成器都可以带一个守卫,以if开头的Boolean表达式 (if前并没有分号)

  1. scala> for(i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " ")

  2. 12 13 21 23 31 32

  • for推导式:for循环的循环以yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值

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

  2. res2: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)

函数

  • 函数定义:需要给出函数名、参数和函数体,格式如下

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

  • 必须给出所有参数的类型

  • 递归函数必须指定返回值类型

  1. def fac(n: Int) : Int = if(n <= 0) 1 else n * fac(n - 1)

  • 不需要 return语句

  • 有 = 等号连接函数体

  • 默认参数和带名参数

  1. scala> def decorate(str: String, left: String = "[", right: String = "]") = left + str + right

  2. decorate: (str: String, left: String, right: String)String

  3. scala> decorate("Hello World")

  4. res3: String = [Hello World]

  5. scala> decorate("Hello World", "<", ">")

  6. res4: String = <Hello World>

  • 也可以在提供参数值时指定参数名,这样就可与函数定义参数列表的顺序不一致

  1. scala> decorate(left = "<<", str = "Hello Scala", right = ">>")

  2. res5: String = <<Hello Scala>>

  • 可以混用未命名参数和带名参数,只要未命名的参数排在前面即可

  1. scala> decorate("Hello Spark", right = "]<<")

  2. res6: String = [Hello Spark]<<

  3. 相当于

  4. scala> decorate("Hello Spark", "[", "]<<")

  • 实现一个可以接受可变长参数列表的函数

  1. scala> def sum(args: Int*) = {

  2.     | var result = 0

  3.     | for (arg <- args) result += arg

  4.     | result

  5.     | }

  6. sum: (args: Int*)Int

  7. scala> val s = sum(1, 3, 5, 7)

  8. s: Int = 16

  • 可以使用 _*将一个整数区间转换成参数序列

  1. 直接使用会抛出如下错误:

  2. scala> val ss = sum(1 to 5)

  3. <console>:8: error: type mismatch;

  4. found   : scala.collection.immutable.Range.Inclusive

  5. required: Int

  6.       val ss = sum(1 to 5)

  7. // 正确的使用方式      

  8. scala> val ss = sum(1 to 5: _*)

  9. ss: Int = 15

  • 如果函数体包含在花括号当中,但没有前面的 =号,返回类型是Unit,这样的函数被称做过程。过程不返回值,调用它仅仅是为了它的副作用。

  • 当val被声明为lazy时,它的始始化将被推迟,直到首次对它取值。

  1. lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString

  2. 可以故意把文件名写错,试一下在初始化语句被执行的时候会不会报错(只有访问words时才提示文件未找到)


敬请期待下一篇~



原文作者:HelloTech技术派;如有侵权,请联系管理员删除。

下一篇: 2017内容汇总
请登录后发表评论 登录
全部评论

注册时间:2017-12-05

  • 博文量
    181
  • 访问量
    73730