0
点赞
收藏
分享

微信扫一扫

Scala控制结构和函数

何晓杰Dev 2022-02-24 阅读 95


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

If else

Scala控制结构和函数_java

s为什么有值?

If 语句的返回类型取决于最后一条语句。
语句后面的分号不是必须的
Scala 没有三元运算符,不需要,if else替代了三元运算符

If 表达式会有一个返回值类型,如果 if 或者 else 返回的类型不一样,就

返回 Any 类型(所有类型的公共超类型)

Scala控制结构和函数_scala_02

如果缺少一个判断,什么都没有返回,但是 Scala 认为任何表达式都会

有值,对于空值,使用 Unit 类,写做()【叫做无有用占位符,相当于 java中的 void】

Scala控制结构和函数_java_03

注 :行尾的位置不需要分号,只要能够从上下文判断出语句的终止即可。但是如果在单行中写多个语句,则需要分号分割 。在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推导式可以引入变量

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 .... ")
}



举报

相关推荐

0 条评论