控制结构和函数

版权声明:有一种生活不去经历不知其中艰辛,有一种艰辛不去体会,不会知道其中快乐,有一种快乐,没有拥有不知其中纯粹 https://blog.csdn.net/wwwzydcom/article/details/84679973

在Scala中 ,几乎所有语法结构都有值

If else

在这里插入图片描述
s为什么有值?
If 语句的返回类型取决于最后一条语句。
语句后面的分号不是必须的
Scala 没有三元运算符,不需要,if else替代了三元运算符

If 表达式会有一个返回值类型,如果 if 或者 else 返回的类型不一样,就
返回 Any 类型(所有类型的公共超类型)
在这里插入图片描述
如果缺少一个判断,什么都没有返回,但是 Scala 认为任何表达式都会
有值,对于空值,使用 Unit 类,写做()【叫做无有用占位符,相当于 java中的 void】
在这里插入图片描述
注 :行尾的位置不需要分号,只要能够从上下文判断出语句的终止即可。但是如果在单行中写多个语句,则需要分号分割 。在Scala 中, {}块,其结果也是一个表达式。块中最后一个表达式的值就是块的值。

While表达式

Scala 提供和 Java 一样的 while 和 do 循环,与 If 语句不同,While 语句
本身没有值,即整个 While 语句的结果是 Unit 类型的()。

while (n > 0) {
r = r * n
n -= 1
println (r)
}
do{
r = r * n
n -= 1
println (r)
} while(n > 0)

注: scala并没有提供break和contine语句来退出循环,如果退出使用

1.使用Boolean型的控制变量
2. 使用嵌套函数,从函数中return
3. 使用Break对象的break方法

import scala.util.control.Breaks._ //手动引入
object Break {
  def main(args: Array[String]): Unit = {
    var r = 1
    var n = 10

    breakable{		//传递值
      while(n > 0){
        r = r *n
        n -= 1
        println(n)
        if (n == 5) break //
      }
    }
  }
}

for表达式

Scala 也为 for 循环这一常见的控制结构提供了非常多的特性,这些 for
循环的特性被称为 for 推导式(for comprehension)或 for 表达式(for
expression)

推导式一词起源于函数式编程:

for (i <- -1 to 3; j <- 1 to 3) println(i+" "+j+" ")

像变量名 <- 集合 这样的表达式被称为生成器表达式,会基于集合生成单独的数值

保护式:也叫守卫,可以添加一个或者多个守卫,不需要continue语句

 for (i <- 1 to 3;j<- 1 to 3 if i != j)println(i+" "+j)

for推导式可以引入变量

扫描二维码关注公众号,回复: 4330570 查看本文章
for (i <- 1 to 3; from = 4 -i)println( from +" ")

需要返回值怎么办?

使用yield关键字在for表达式中生成新的集合,for-yield表达式所生成的集合类型将根据所遍历的集合类型推导而出

  val result = for( i <- 1 to 10)yield i %3
    println(result)

{}和()对于 for 表达式来说都可以,for 推导式有一个不成文的约定:当
for 推导式仅包含单一表达式时使用原括号,当其包含多个表达式时使用大括号。值得注意的是,使用原括号时,早前版本的 Scala 要求表达式之间必须使用分号

函数

java中一般通过静态方法模拟
函数的定义

def 函数名(参数名 : 类型)[: 返回类型] = 函数体

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

递归函数
def res(n:Int) : Int = if(n <= 0) 1 else n*res(n -1 )
递归函数必须有返回值,且指定函数返回值类型

函数参数默认值
参数类型后面设置默认值

   def decotate(str:String,left: String ="[",right: String = "]") = left + str + right
    //未设置参数,默认[]
    println(decotate("hello"))
    //设置参数 
    println(decotate("hello","<<<",">>>"))

函数的命名参数
不按照原先函数的参数顺序,指定参数顺序

println(decotate(left = "<<<",right = ">>>",str = "你好"))

变长函数

  def sum(args : Int*): Int ={
      var result = 0
      for (arg <- args) result += arg
      result
    }

    println(sum(1,4,5,6))

需要指定返回类型,否则结果会被舍弃

*_告诉编译器 1 to 5 当做参数序列处理 Range

  println(sum(3 to 6 : _*))

head 和 tail

head是第一个元素,tail是剩下的元素的集合

def reds(qarg: Int*) : Int ={
      if (qarg.length == 0) 0
      else qarg.head + reds(qarg.tail : _*)
    }

    println(reds(4,2,4,59,76))

注:

  1. Scala可以通过=右边表达式,推断出函数的返回类型,如果函数体需要多个表达式,可以用代码块{}
    2.可以将return当做函数版本的break语句
  2. 递归函数一定要指定返回类型
  3. 变长参数通过*来指定,所有参数会转换为一个序列
  4. _* 告诉编译器,Range当做参数序列化处理
  5. Head是获取首元素,tail是获取剩下元素的序列

过程:

没有返回值的函数:返回类型是unit,没有 = 号

def box(s : String) {  // Look carefully: no =
val border = " "- - " * s.length + " " --\ \n n" "
println(" "\ \n n " + border +  "|" + s +  "|\ \n n " + border)
}

懒值

当val被声明为lazy时,初始化将会被延迟,直到我们对此首次取值

使用事项:

  1. 用于初始化开销比较大的语句
  2. 解决循环依赖问题 A依赖B B依赖A
  3. 是开发懒数据结构的基础
 def lazyed() {
      lazy val property = init();//没有使用lazy修饰
      println("after init()")
      println(property)
    }

异常

当碰到异常情况时,方法抛出一个异常,终止方法本身执行,异常传递给其调用者,调用者可以处理该异常,也可以升级到它的调用者,运行系统会一直这样升级异常,直到调用者处理,如果没有处理,终止程序

Scala的异常工作机制和java一样,但是Scala没有受检异常,不需要声明函数或者方法可能抛出某种异常,受检异常在编译器被检查,java必须声明方法所会抛出的异常类型

抛出异常: 用throw关键字,抛出一个异常对象,所有的异常都是Trowable的子类型,throw表达式都是有类型的,为Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方

//并不像 Java 代码那样,需要声明方法会抛出异常,这给程序员省去理论很多烦恼。方法上也不需要声明
def divide(x: Int, y: Int): Int = {
if (y == 0) throw new Exception("Divide by zero")
else x / y
}

捕捉异常
在 Scala 里,借用了模式匹配的思想来做异常的匹配,因此,在 catch 的
代码里,是一系列 case 字句。

异常捕捉的机制与其他语言中一样,如果有异常发生,catch 字句是按次
序捕捉的。因此,在 catch 字句中,越具体的异常越要靠前,越普遍的异常越靠后。 如果抛出的异常不在 catch 字句中,该异常则无法处理,会被升级到调用者处。

异常捕获通常采用模式匹配的语法:

try {
process(in)
}  catch {
case ex: IOException => println(ex)
}  finally {
in.close()
}

finally 字句用于执行不管是正常处理还是有异常发生时都需要执行的步
骤,一般用于对象的清理工作。

注:

  1. Throw的类型为Nothing,存在exception的if语句类型返回类型

异常代码练习

     def root(x : Double) = if (x>0){sqrt(x)}else throw new IllegalArgumentException(" s" +
      " should not be negative ")
    try{
      println(root(4))
      println(root(-5))
    }catch {
      case e: Exception => println(e)
    }finally {
      println(" finally .... ")
    }

猜你喜欢

转载自blog.csdn.net/wwwzydcom/article/details/84679973